Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read & writing arrays of Parcelable objects

I have following class which reads and writes an array of objects from/to a parcel:

class ClassABC extends Parcelable {     MyClass[] mObjList;      private void readFromParcel(Parcel in) {         mObjList = (MyClass[]) in.readParcelableArray(                 com.myApp.MyClass.class.getClassLoader()));     }      public void writeToParcel(Parcel out, int arg1) {         out.writeParcelableArray(mObjList, 0);     }      private ClassABC(Parcel in) {         readFromParcel(in);     }      public int describeContents() {         return 0;     }      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];         }     }; } 

In above code I get a ClassCastException when reading readParcelableArray:

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

What is wrong in above code? While writing the object array, should I first convert the array to an ArrayList?

UPDATE:

Is it OK to convert an Object array to an ArrayList and add it to parcel? For instance, when writing:

    ArrayList<MyClass> tmpArrya = new ArrayList<MyClass>(mObjList.length);     for (int loopIndex=0;loopIndex != mObjList.length;loopIndex++) {         tmpArrya.add(mObjList[loopIndex]);     }     out.writeArray(tmpArrya.toArray()); 

When reading:

    final ArrayList<MyClass> tmpList =              in.readArrayList(com.myApp.MyClass.class.getClassLoader());     mObjList= new MyClass[tmpList.size()];     for (int loopIndex=0;loopIndex != tmpList.size();loopIndex++) {         mObjList[loopIndex] = tmpList.get(loopIndex);     } 

But now I get a NullPointerException. Is above approach is correct? Why it is throwing an NPE?

like image 258
User7723337 Avatar asked Apr 09 '12 09:04

User7723337


People also ask

Is red the past tense of read?

For example, the past tense of "to read", which is read, shares the same sound as red—but not the same meaning. The present tense to read (rhymes with deed) sounds like reed, but as with the past tense of read and the word red, that similar sound is all the words have in common.

Is read or read?

As previously mentioned, the past tense of read is read. These words are spelled the same but pronounced differently. Read in the present tense has a long “e” sound, and read in the past tense has a short “e” sound. The only way to know which word is meant when it is written is by the context of the sentence.

Have a read meaning?

"A read" is "a period of time spent reading". It means a half-hour or more, all at once, not a minute or two. He might read things 50 times a day, but they aren't part of this quiet period, when he does nothing but read, with no interruptions. That is "having a read".

What is the two meaning of read?

1a : to perform the act of reading words : read something. b(1) : to learn something by reading. (2) : to pursue a course of study. 2a : to yield a particular meaning or impression when read. b : to be readable or read in a particular manner or to a particular degree this book reads smoothly.


Video Answer


2 Answers

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); } 
like image 114
Michael Avatar answered Sep 20 '22 05:09

Michael


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);   } 
like image 22
yorkw Avatar answered Sep 21 '22 05:09

yorkw