Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parcel Unmarshalling unknown type code

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
like image 520
ManiacalG Avatar asked Oct 30 '13 02:10

ManiacalG


3 Answers

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.

like image 102
Ricardo Avatar answered Nov 08 '22 00:11

Ricardo


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).

like image 29
Json Avatar answered Nov 08 '22 02:11

Json


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.

like image 3
HyperionX Avatar answered Nov 08 '22 00:11

HyperionX