We are getting this error in the Crash reports logged by play store. Cant replicate this in all our testing. Does anyone else have the same problem or solution ? Thing is, w
I got this error when I was over reading the Parcel source, to save on a Map instead of checking the return value is null as:
String tag = in.readString();
Double value = in.readDouble();
while (tag != null && value != null) {
this.observations.put(tag, value);
tag = in.readString();
value = in.readDouble();
};
One should store an int to use to iterate correctly on the Parcel:
int numObservations = in.readInt();
String key;
Double value;
for (int i = 0; i < numObservations; i++) {
key = in.readString();
value = in.readDouble();
map.put(tag, value);
}
If you have your own SavedState class, make sure that it is not Proguarded and neither is it's CREATOR
static attribute.
Use something like:
# Keeping *SavedState and *SavedState#CREATOR
-keep public final class * extends android.view.AbsSavedState
-keepclassmembers public final class * extends android.view.AbsSavedState { *; }
I occurred the same error when read parcel.
Check the order and count while read/write of your Parcelable classes and respective sub-classes.
Check the order of your read
and write
in your Parcelable classes and respective sub-classes.
The order in which you writeToParcel
should be the same order as you read within your MyParcelable(Parcel in)
method.
In my case I was trying to assign an arrayList to a List and that triggers that error
I was having the issue with a custom view having its own implementation of View.BaseSavedState. It turned out that the writeToParcel() method there had method calls in the wrong order.
It was annoying to find the problem and I needed to step debug the Android SDK all the way to the Bundle class, where unparcel() is called:
synchronized void unparcel() {
if (mParcelledData == null) {
return;
}
int N = mParcelledData.readInt();
if (N < 0) {
return;
}
if (mMap == null) {
mMap = new HashMap<String, Object>(N);
}
mParcelledData.readMapInternal(mMap, N, mClassLoader);
mParcelledData.recycle();
mParcelledData = null;
}
Line 223 of your log is exactly the readMapInternal() call. There the Parcel object will iterate through its items, reading the values one by one. The problem usually occurs if something was written in the wrong order. The method Parcel.readValue(ClassLoader loader) will read them in the order they were written but if you have custom views or objects, if they were written in an order different than the one you are now reading them, something wrong will happen in the NEXT item to read.
So I found the problem by identifying the last item that was read successfully. You can usually identify that (if it's a custom view or object) by checking its creator class name. Check the Parcel class' method readParcelableCreator():
public final <T extends Parcelable> Parcelable.Creator<T> readParcelableCreator(
ClassLoader loader) {
String name = readString();
if (name == null) {
return null;
}
...
}
You can inspect the name string for the class of the creator. If it's a custom one, you can immediately identify it. Then, if the next reading crashes your app, you can be almost sure that the culprit was the previous read.
Hope it helps.