我们在Play商店记录的崩溃报告中收到此错误。不能在我们所有的测试中重复这一点。还有其他人有相同的问题或解决方案吗?
事实是,我们什至不知道该怎么做才能复制此错误。

所有Parcelable对象都定义了 CREATOR,writeToParcel()和构造器。初始化所有列表和复杂类型,并进行空检查。

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

最佳答案

我遇到了一个自定义 View 的问题,该 View 具有自己的View.BaseSavedState实现。原来,那里的writeToParcel()方法以错误的顺序调用了方法。

发现问题很烦人,我需要逐步调试Android SDK一直到Bundle类,其中unparcel()称为:

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;
}

日志的第223行恰好是readMapInternal()调用。在那里,宗地对象将遍历其项,一一读取值。如果以错误的顺序写入内容,通常会出现此问题。 Parcel.readValue(ClassLoader loader)方法将按照它们的写入顺序读取它们,但是如果您具有自定义 View 或对象,并且它们的写入顺序与您现在所阅读的 View 或对象的顺序不同,则在下一个要阅读的项目。

因此,我通过确定成功读取的最后一个项目发现了问题。通常,您可以通过检查其创建者类名称来识别(如果它是自定义 View 或对象)。检查宗地类的方法readParcelableCreator():
public final <T extends Parcelable> Parcelable.Creator<T> readParcelableCreator(
        ClassLoader loader) {
    String name = readString();
    if (name == null) {
        return null;
    }
...
}

您可以检查创建者类的名称字符串。如果是自定义的,则可以立即将其识别出来。然后,如果下一次阅读使您的应用程序崩溃,则几乎可以确定罪魁祸首是上一次阅读。

希望能帮助到你。

09-11 19:14
查看更多