21

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, we dont even know what to do to replicate this bug.

All Parcelable objects have CREATOR, writeToParcel() and contructor defined. All Lists and complex types are initialised and null checked.

java.lang.RuntimeException: Unable to start activity ComponentInfo{au.com.company/au.com.company.DetailsActivity}: java.lang.RuntimeException: Parcel android.os.Parcel@42d6e270: Unmarshalling unknown type code 6881381 at offset 11268
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2247)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2297)
at android.app.ActivityThread.access$700(ActivityThread.java:152)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1282)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5328)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@42d6e270: Unmarshalling unknown type code 6881381 at offset 11268
at android.os.Parcel.readValue(Parcel.java:2032)
at android.os.Parcel.readMapInternal(Parcel.java:2225)
at android.os.Bundle.unparcel(Bundle.java:223)
at android.os.Bundle.getSparseParcelableArray(Bundle.java:1240)
at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:861)
at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1104)
at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1086)
at android.support.v4.app.FragmentManagerImpl.dispatchCreate(SourceFile:1872)
at android.support.v4.app.FragmentActivity.onCreate(SourceFile:215)
at android.support.v7.app.ActionBarActivity.onCreate(SourceFile:97)
at au.com.company.DetailsActivity.onCreate(SourceFile:40)
at android.app.Activity.performCreate(Activity.java:5250)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
... 11 more
ManiacalG
  • 221
  • 1
  • 2
  • 7
  • Having a very simmilar exception after enabeling proguard, not solved my self yet. – Rolf ツ Nov 04 '13 at 14:58
  • Found out in some places that we were either ordering the fields wrong or missing some fields between the create/constructor and writeToParcel. Also added CREATOR to all nested classes and it went away. Best is to split the screen with the same file and match each field for each nested class in each of the methods. Gruesome work, but don't see that error anymore. – ManiacalG Jan 21 '14 at 22:42
  • Maybe this can help someone. Enabling developer mode and always kill activities helps reproduce this 100% of the time – Aerim Mar 29 '21 at 12:04

7 Answers7

23

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.

Ricardo
  • 7,785
  • 8
  • 40
  • 60
  • I get your explanation but haven’t quite understood how to debug this stuff :) any help? I have double checked all my SavedStates and orders are OK. – natario Jan 09 '16 at 14:12
  • I the proposed solution doesn't %100 worked for me but it gave me lead to investigate the custom View.BaseSavedState implementation that I have on one of custom views. – Hadi Tok Jun 29 '17 at 09:50
8

I also got this error but I found the problem. I had changed a variable from long to int but forgot to change the following:

I had parcel.writeLong(number) and then read it back as number=parcel.readInt(). The correct is parcel.writeInt(number).

Sufian
  • 6,405
  • 16
  • 66
  • 120
Paintoshi
  • 816
  • 10
  • 12
  • The exact mistake I was making! – Sufian Jun 20 '15 at 09:49
  • My mistake was doing parcel.writeValue(object) combined with parcel.readParcelable(Class.class.getClassLoader()). Had to use parcel.writeParcelable() and parcel.readParcelable() – Pedro Romão Feb 26 '19 at 09:54
3

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.

HyperionX
  • 1,332
  • 2
  • 17
  • 31
0

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);
}
Bruno Peres
  • 2,980
  • 1
  • 21
  • 19
0

I occurred the same error when read parcel.

Check the order and count while read/write of your Parcelable classes and respective sub-classes.

Karen Chang
  • 121
  • 1
  • 2
0

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 { *; }
William
  • 20,150
  • 8
  • 49
  • 91
-1

In my case I was trying to assign an arrayList to a List and that triggers that error

Stefan Ticu
  • 2,093
  • 1
  • 12
  • 21