Unmarshalling parcelables task

I have several classes that implement Parcelable , and some of these classes contain each other as properties. I collect classes in Parcel to pass them between actions. Marshalling them to the site works great, but when I try to untie them, I get the following error:

... AndroidRuntime E Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: schemas.Arrivals.LocationType AndroidRuntime E at android.os.Parcel.readParcelable(Parcel.java:1822) AndroidRuntime E at schemas.Arrivals.LayoverType.<init>(LayoverType.java:121) AndroidRuntime E at schemas.Arrivals.LayoverType.<init>(LayoverType.java:120) AndroidRuntime E at schemas.Arrivals.LayoverType$1.createFromParcel(LayoverType.java:112) AndroidRuntime E at schemas.Arrivals.LayoverType$1.createFromParcel(LayoverType.java:1) AndroidRuntime E at android.os.Parcel.readTypedList(Parcel.java:1509) AndroidRuntime E at schemas.Arrivals.BlockPositionType.<init>(BlockPositionType.java:244) AndroidRuntime E at schemas.Arrivals.BlockPositionType.<init>(BlockPositionType.java:242) AndroidRuntime E at schemas.Arrivals.BlockPositionType$1.createFromParcel(BlockPositionType.java:234) AndroidRuntime E at schemas.Arrivals.BlockPositionType$1.createFromParcel(BlockPositionType.java:1) ... 

Class LayoverType (where it does not work):

 public class LayoverType implements Parcelable { protected LocationType location; protected long start; protected long end; public LayoverType() {} public LocationType getLocation() { return location; } public void setLocation(LocationType value) { this.location = value; } public long getStart() { return start; } public void setStart(long value) { this.start = value; } public long getEnd() { return end; } public void setEnd(long value) { this.end = value; } // ********************************************** // for implementing Parcelable // ********************************************** @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeParcelable(location, flags); dest.writeLong(start); dest.writeLong(end ); } public static final Parcelable.Creator<LayoverType> CREATOR = new Parcelable.Creator<LayoverType>() { public LayoverType createFromParcel(Parcel in) { return new LayoverType(in); } public LayoverType[] newArray(int size) { return new LayoverType[size]; } }; private LayoverType(Parcel dest) { location = (LocationType) dest.readParcelable(null); // it failing here start = dest.readLong(); end = dest.readLong(); } } 

Here's the LocationType class:

 public class LocationType implements Parcelable { protected int locid; protected String desc; protected String dir; protected double lat; protected double lng; public LocationType() {} public int getLocid() { return locid; } public void setLocid(int value) { this.locid = value; } public String getDesc() { return desc; } public void setDesc(String value) { this.desc = value; } public String getDir() { return dir; } public void setDir(String value) { this.dir = value; } public double getLat() { return lat; } public void setLat(double value) { this.lat = value; } public double getLng() { return lng; } public void setLng(double value) { this.lng = value; } // ********************************************** // for implementing Parcelable // ********************************************** @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt (locid); dest.writeString(desc ); dest.writeString(dir ); dest.writeDouble(lat ); dest.writeDouble(lng ); } public static final Parcelable.Creator<LocationType> CREATOR = new Parcelable.Creator<LocationType>() { public LocationType createFromParcel(Parcel in) { return new LocationType(in); } public LocationType[] newArray(int size) { return new LocationType[size]; } }; private LocationType(Parcel dest) { locid = dest.readInt (); desc = dest.readString(); dir = dest.readString(); lat = dest.readDouble(); lng = dest.readDouble(); } } 

Update 2 . As far as I can tell, it does not work on the following code snippet (from Source ):

 Class c = loader == null ? Class.forName(name) : Class.forName(name, true, loader); 

Why can't he find a class? It exists and implements Parcelable .

+55
java android marshalling parcelable
Jan 03 '09 at 21:02
source share
9 answers

Because the answer was not answered by the answer, but in the comment I will post the answer: As an @ Max-Gontar pointer, you must use LocationType.class.getClassLoader () to get the correct ClassLoader and get rid of the ClassNotFound exception, i.e.:

in.readParceleable(LocationType.class.getClassLoader());

+80
Feb 06 '11 at 18:25
source share

I had the same problem with the following installation: some handler creates a message and sends it through Messenger to the remote service.

The message contains a package in which I put my descendant:

 final Message msg = Message.obtain(null, 0); msg.getData().putParcelable("DOWNLOADFILEURLITEM", downloadFileURLItem); messenger.send(msg); 

I had the same exception when the remote service tried to parallelize. In my case, I observed that the remote service is indeed a separate os process. Therefore, I had to install the current classloader, which will be used by the unparcelling process on the service side:

 final Bundle bundle = msg.getData(); bundle.setClassLoader(getClassLoader()); DownloadFileURLItem urlItem = (DownloadFileURLItem) bundle.getParcelable("DOWNLOADFILEURLITEM"); 

Bundle.setClassLoader sets the class loader, which is used to load the corresponding Parcelable classes. In the remote service, you need to reset this for the current classloader.

+32
Sep 27 '10 at 18:41
source share

I found that the problem was that I did not pass my ClassLoader applications to the unmarshalling function:

 in.readParceleable(getContext().getClassLoader()); 

Instead

 in.readParceleable(null); 

OR

 in.readParceleable(MyClass.class.getClassLoader()); 
+9
Mar 03 '10 at 12:22
source share

Just adding my 2 cents here because I lost more than half a day scratching my head. You may get this error if you do not set the writing methods and read the methods in the same order. For example, the following is not true:

  @Override // Order: locid -> desc -> lat -> dir -> lng public void writeToParcel(Parcel dest, int flags) { dest.writeInt (locid); dest.writeString(desc); dest.writeDouble(lat); dest.writeString(dir); dest.writeDouble(lng); } // Order: locid -> desc -> dir -> lat -> lng private LocationType(Parcel dest) { locid = dest.readInt(); desc = dest.readString(); dir = dest.readString(); lat = dest.readDouble(); lng = dest.readDouble(); } 

By the way, the author did it right, but one day he can help someone.

+7
Nov 09 2018-11-11T00:
source share

I am not very good at Parcelable, but if it is something like Serialization, every call to write an object that implements the interface will call a writeToParcel () call recursively. Therefore, if something on the call stack fails or writes a null value, the class that initiated the call may not be built correctly.

Try: Track the stack of calls to writeToParcel () through all classes, starting with the first call to writeToParcel (), and make sure all values ​​are sent correctly.

+6
Jan 03 '09 at 21:35
source share

I also got a ClassNotFoundException and posted my bc solution, and the answers led me in the right direction. My scenario is that I have nested objects. Object A contains the ArrayList of object B. Both implement Parcelable. Entering a list of object B in class A:

 @Override public void writeToParcel(Parcel dest, int flags) { ... dest.writeList(getMyArrayList()); } 

Reading a list in class A:

 public ObjectA(Parcel source) { ... myArrayList= new ArrayList<B>(); source.readList(myArrayList, B.class.getClassLoader()); } 

Thank!

+6
Feb 12 '13 at 11:15
source share

Instead of using writeParcelable and readParcelable directly, use writeToParcel and createFromParcel. Therefore, the best code:

 @Override public void writeToParcel(Parcel dest, int flags) { location.writeToParcel(dest, flags); dest.writeLong(start); dest.writeLong(end ); } public static final Parcelable.Creator<LayoverType> CREATOR = new Parcelable.Creator<LayoverType>() { public LayoverType createFromParcel(Parcel in) { return new LayoverType(in); } public LayoverType[] newArray(int size) { return new LayoverType[size]; } }; private LayoverType(Parcel dest) { location = LocationType.CREATOR.createFromParcel(dest); start = dest.readLong(); end = dest.readLong(); } 
+5
Dec 26 2018-10-12-26
source share

Well, I had the same problem and it’s very stupid to solve it, that I don’t know if this is called a solution at all.

lets say that you have this class that you want to transfer to another event.

 public class Person implements Parcelable,Serializable{ public String Name; public int Age; @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(age); } public SeriesInfo(Parcel in) { age= in.readInt(); //her was my problem as I have put age befor name //while in the writeToParcel function I have defined //dest.writeInt(age) after in.readString();???!!!! name= in.readString(); } } 

Thats it When I changed:

 dest.writeString(name); dest.writeInt(age); 

to

 dest.writeInt(age); dest.writeString(name); 

The problem is solved ??? !!!!

+1
Jan 05 '16 at 2:59
source share

If you have an object with a property like List objects, you must pass the class loader when you read the property, for example:

 public class Mall implements Parcelable { public List<Outstanding> getOutstanding() { return outstanding; } public void setOutstanding(List<Outstanding> outstanding) { this.outstanding = outstanding; } protected Mall(Parcel in) { outstanding = new ArrayList<Outstanding>(); //this is the key, pass the class loader in.readList(outstanding, Outstanding.class.getClassLoader()); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeList(outstanding); } public static final Parcelable.Creator<Mall> CREATOR = new Parcelable.Creator<Mall>() { public Mall createFromParcel(Parcel in) { return new Mall(in); } public Mall[] newArray(int size) { return new Mall[size]; } }; } 

Note. It is important that the Outstanding class implement the Parceable interface.

0
Nov 21 '13 at 21:59
source share



All Articles