Read & writing arrays of Parcelable objects Read & writing arrays of Parcelable objects android android

Read & writing arrays of Parcelable objects


You need to write the array using the Parcel.writeTypedArray() method and read it back with the Parcel.createTypedArray() method, like so:

MyClass[] mObjList;public void writeToParcel(Parcel out) {    out.writeTypedArray(mObjList, 0);}private void readFromParcel(Parcel in) {    mObjList = in.createTypedArray(MyClass.CREATOR);}

The reason why you shouldn't use the readParcelableArray()/writeParcelableArray() methods is that readParcelableArray() really creates a Parcelable[] as a result. This means you cannot cast the result of the method to MyClass[]. Instead you have to create a MyClass array of the same length as the result and copy every element from the result array to the MyClass array.

Parcelable[] parcelableArray =        parcel.readParcelableArray(MyClass.class.getClassLoader());MyClass[] resultArray = null;if (parcelableArray != null) {    resultArray = Arrays.copyOf(parcelableArray, parcelableArray.length, MyClass[].class);}


ERROR/AndroidRuntime(5880): Caused by: java.lang.ClassCastException: [Landroid.os.Parcelable;

According to the API, readParcelableArray method returns Parcelable array (Parcelable[]), which can not be simply casted to MyClass array (MyClass[]).

But now i get Null Pointer Exception.

It is hard to tell the exact cause without the detailed exception stack trace.


Suppose you have made MyClass implements Parcelable properly, this is how we usually do for serialize/deserialize a array of parcelable objects:

public class ClassABC implements Parcelable {  private List<MyClass> mObjList; // MyClass should implement Parcelable properly  // ==================== Parcelable ====================  public int describeContents() {    return 0;  }  public void writeToParcel(Parcel out, int flags) {    out.writeList(mObjList);  }  private ClassABC(Parcel in) {    mObjList = new ArrayList<MyClass>();    in.readList(mObjList, getClass().getClassLoader());   }  public static final Parcelable.Creator<ClassABC> CREATOR = new Parcelable.Creator<ClassABC>() {    public ClassABC createFromParcel(Parcel in) {      return new ClassABC(in);    }    public ClassABC[] newArray(int size) {      return new ClassABC[size];    }  };}

Hope this helps.

You can also use the following methods:

  public void writeToParcel(Parcel out, int flags) {      out.writeTypedList(mObjList);  }  private ClassABC(Parcel in) {      mObjList = new ArrayList<ClassABC>();      in.readTypedList(mObjList, ClassABC.CREATOR);  }


I had a similar problem, and solved it this way.I defined a helper method in MyClass, for converting an array of Parcelable to an array of MyClass objects:

public static MyClass[] toMyObjects(Parcelable[] parcelables) {    MyClass[] objects = new MyClass[parcelables.length];    System.arraycopy(parcelables, 0, objects, 0, parcelables.length);    return objects;}

Whenever I need to read a parcelable array of MyClass objects, e.g. from an intent:

MyClass[] objects = MyClass.toMyObjects(getIntent().getParcelableArrayExtra("objects"));

EDIT: Here is an updated version of the same function, that I am using more recently, to avoid compile warnings:

public static MyClass[] toMyObjects(Parcelable[] parcelables) {    if (parcelables == null)        return null;    return Arrays.copyOf(parcelables, parcelables.length, MyClass[].class);}