在Android应用程序错误解组自定义parcelable类(Unmarshalling error

2019-07-17 12:07发布

对于我的Android应用程序,我得到几个数据编出的错误,虽然我觉得我做到了这一点,需要妥善保存和载入通过对象的一切Parcelable秒。 你能告诉我什么是错我的代码?

错误1:

java.lang.RuntimeException: Unable to start activity ComponentInfo
Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@41279860: Unmarshalling unknown type code 6619241 at offset 1372
at android.os.Parcel.readValue(Parcel.java:1922)
at android.os.Parcel.readMapInternal(Parcel.java:2094)
at android.os.Bundle.unparcel(Bundle.java:223)
at android.os.Bundle.getParcelable(Bundle.java:1158)
at android.app.Activity.onCreate(Activity.java:860)
at my.app.package.PlayComputer.onCreate(PlayComputer.java:1012)
at android.app.Activity.performCreate(Activity.java:4465)

在1012行MyActivity是调用super.onCreate(savedInstanceState);ActivityonCreate()

protected void onSaveInstanceState(Bundle savedInstanceState) {
    if (myObject == null) {
        savedInstanceState.putParcelable("myObject", null);
    }
    else {
        savedInstanceState.putParcelable("myObject", myObject);
    }
    savedInstanceState.putInt(...);
    savedInstanceState.putString(...);
    savedInstanceState.putBoolean(...);
    super.onSaveInstanceState(savedInstanceState);
}

myObject是类的MyObject ,其具有以下的方法:

public void writeToParcel(Parcel out, int flags) {
    out.writeIntArray(...);
    out.writeInt(...);
    out.writeStringArray(...);
    out.writeString(...);
    out.writeParcelableArray(..., flags);
}

public static final Parcelable.Creator<MyObject> CREATOR = new Parcelable.Creator<MyObject>() {
    public MyObject createFromParcel(Parcel in) {
        try {
            if (in == null) {
                return null;
            }
            else {
                return new MyObject(in);
            }
        }
        catch (Exception e) {
            return null;
        }
    }
    public MyObject[] newArray(int size) {
        return new MyObject[size];
    }
};

private MyObject(Parcel in) {
    in.readIntArray(...);
    ... = in.readInt();
    in.readStringArray(...);
    ... = in.readString();
    ... = (OtherObject[]) in.readParcelableArray(OtherObject.class.getClassLoader());
}

错误2:

java.lang.RuntimeException: Unable to start activity ComponentInfo
Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling:
at android.os.Parcel.readParcelable(Parcel.java:1971)
at android.os.Parcel.readValue(Parcel.java:1859)
at android.os.Parcel.readMapInternal(Parcel.java:2099)
at android.os.Bundle.unparcel(Bundle.java:223)
at android.os.Bundle.getParcelable(Bundle.java:1158)
at android.app.Activity.onCreate(Activity.java:905)
at my.app.package.PlayComputer.onCreate(SourceFile:1012)

相同的文件和类。

错误3:

java.lang.RuntimeException: Unable to start activity ComponentInfo
Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@4051aff8: Unmarshalling unknown type code 7340149 at offset 1276
at android.os.Parcel.readValue(Parcel.java:1913)
at android.os.Parcel.readMapInternal(Parcel.java:2083)
at android.os.Bundle.unparcel(Bundle.java:208)
at android.os.Bundle.getParcelable(Bundle.java:1100)
at my.app.package.PlayComputer.onCreate(SourceFile:1111)

此时,使线(1111)是下述之一:

myObject = (MyObject) savedInstanceState.getParcelable("myObject");

Answer 1:

Android有两个不同的类加载器:框架类加载器(它知道如何加载安卓类)和APK类加载器(它知道如何装载你的代码)。 该APK类加载器具有框架类加载器设置为其父,这意味着它也可以装载Android的类。

错误#2很可能被捆绑使用框架的classloader所以它不知道你的类引起的。 我认为,当Android的需要,以保存捆绑,并(在后台运行时内存不足,例如)以后恢复它会发生这种情况。 您可以通过设置在包中的类加载器APK解决这个问题:

savedInstanceState.setClassLoader(的getClass()getClassLoader());

错误#1和#3是更神秘的,你也许在写空值writeToParcel() Android不喜欢很多我害怕。



Answer 2:

通过它的外观,在createFromParcelnewArray应该重写这样的:

public static final Parcelable.Creator<MyObject> CREATOR = new Parcelable.Creator<MyObject>() {
    @Override
    public MyObject createFromParcel(Parcel in) {
        MyObject myObj = new MyObject();
        myObj.intArray = in.readIntArray(...);
        myObj.intValue = in.readInt(...);
        // ....
        // IN THE SAME ORDER THAT IS WRITTEN OUT AS PER writeToParcel!
        //
        return myObj;
    }
    @Override
    public MyObject[] newArray(int size) {
        return new MyObject[size];
    }
};

编辑:

我忘了提及,对于上述工作,应该有过一个空的构造!

public MyObject(){}


Answer 3:

从捆绑,设定的ClassLoader阅读之前:

bundle.setClassLoader(getClass().getClassLoader());

这救了我的时间!



文章来源: Unmarshalling errors in Android app with custom parcelable classes