Parcelableを実装するときの注意
例えば、Stringの配列をreadする際は、readStringArrayではなく、createStringArrayを使う :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
public class MyData implements Parcelable { private String mStringArray[]; public String[] getStringArray() { return mStringArray; } public void setStringArray(String stringArray[]) { this .mStringArray = stringArray; } private MyData(Parcel in) { mStringArray = in.createStringArray(); } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeStringArray(mStringArray); } @Override public int describeContents() { return 0 ; } public static final Creator<MyData> CREATOR = new Creator<MyData>() { @Override public MyData createFromParcel(Parcel in) { return new MyData(in); } @Override public MyData[] newArray( int size) { return new MyData[size]; } }; } |
もし、readStringArray使った場合、画面回転程度の読み込みではエラーは出ないが、「アクティビティ破棄する(アクティビティを保持しない)」設定をオンにした状態で再起動する(ホームボタン→アプリ起動)と、私の環境では次のエラーが出た.
1 2 3 |
Caused by: java.lang.NullPointerException: Attempt to get length of null array ... at MainActivity.onCreate(MainActivity.java:xxx) |
Parcelableでデータを受渡しするときの注意
特に、onRestoreInstanceState、onSavedInstanceStateでアクティビティの復元を行う際、putParcelableArrayやgetParcelableArrayなどで、Parcelableの配列を使わないほうが良い.
1 2 3 4 5 6 7 8 9 |
... private MyData myData[]; ... @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { ... myData = (MyData[])savedInstanceState.getParcelableArray(Key1); ... } |
上のようにキャストしないとコンパイルエラーが発生するが、アクティビティが破棄された後(「アクティビティを破棄する」設定をオンにしてアプリケーションを終了する)では、Bundle内で型の情報が保持されないようで、次のようなエラーが出た.
1 2 |
Caused by: java.lang.ClassCastException: android.os.Parcelable[] cannot be cast to com.foo.example.MyData[] at com.foo.example.MainActivity.onViewStateRestored(MainActivity.java:xxx) |
代わりに、putParcelableArrayListやgetParcelableArrayListを使うことで、このエラーを回避できた.
1 2 3 4 5 6 7 8 9 |
... private ArrayList<MyData> myData; ... @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { ... myData = savedInstanceState.getParcelableArrayList(Key1); ... } |