对于我的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)
MyActivity
中的第1012行是super.onCreate(savedInstanceState);
Activity
中onCreate()
的来电。
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");
答案 0 :(得分:46)
Android有两个不同的类加载器:框架类加载器(它知道如何加载Android类)和APK类加载器(它知道如何加载代码)。 APK类加载器将框架类加载器设置为其父类,这意味着它还可以加载Android类。
错误#2可能是由Bundle使用框架类加载器引起的,所以它不知道你的类。我认为这可能发生在Android需要保留Bundle并稍后恢复它时(例如在后台内存不足时)。您可以通过在捆绑包上设置APK类加载器来解决此问题:
savedInstanceState.setClassLoader(的getClass()getClassLoader());
错误#1和#3更加神秘,您是否可以在writeToParcel()
中写入空值?我不太喜欢Android。
答案 1 :(得分:2)
从表面上看,createFromParcel
和newArray
应该被覆盖:
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(){}
答案 2 :(得分:2)
在从bundle中读取之前,请设置ClassLoader:
data_hash.dig('data', 'children', 0, 'data', 'body')
这节省了我的时间!