Android &引用;BadParcelableException:解包时ClassNotFoundException<;myclass>&引用;使用Parcel.read方法时,该方法将类加载器作为参数
给定一个自定义类Android &引用;BadParcelableException:解包时ClassNotFoundException<;myclass>&引用;使用Parcel.read方法时,该方法将类加载器作为参数,android,marshalling,unmarshalling,parcel,Android,Marshalling,Unmarshalling,Parcel,给定一个自定义类org.example.app.MyClass实现了Parcelable,我想将列表写入一个地块。我和他一起做编组 List<MyClass> myclassList = ... parcel.writeList(myclassList); List myclassList=。。。 包裹列表(myclassList); 每当我试图用你的名字来解压这个班级时 List<MyClass> myclassList = new ArrayList<
org.example.app.MyClass实现了Parcelable
,我想将列表
写入一个地块。我和他一起做编组
List<MyClass> myclassList = ...
parcel.writeList(myclassList);
List myclassList=。。。
包裹列表(myclassList);
每当我试图用你的名字来解压这个班级时
List<MyClass> myclassList = new ArrayList<MyClass>();
parcel.readList(myclassList, null);
List myclassList=new ArrayList();
parcel.readList(myclassList,空);
在解组org.example.app.MyClass时,存在一个“BadParcelableException:ClassNotFoundException”
异常
这里怎么了?为什么找不到该类?当您将
null
作为类加载器参数时,不要使用框架类加载器将自定义类(即,由应用程序提供而不是由Android框架提供的类)解组。使用应用程序类加载器:
parcel.readList(myclassList, getClass().getClassLoader());
无论何时Parcel.read*()
方法也有一个类加载器作为参数(例如),并且您想要从Parcel
中读取应用程序类,请使用可以通过getClass().getClassLoader()
检索的应用程序类加载器
背景:Android附带两个类加载器:系统类加载器,可以加载除应用程序提供的类以外的所有系统类;以及应用程序类加载器,它将系统类加载器设置为其父类,因此能够加载所有类。如果将null作为类装入器,则会导致
感谢alexanderblom为我提供的帮助,使我走上了正确的道路。我相信更正确的形式是:
List<MyClass> myclassList = new ArrayList<MyClass>();
parcel.readList(myclassList, MyClass.class.getClassLoader());
List myclassList=new ArrayList();
parcel.readList(myclassList,MyClass.class.getClassLoader());
因为这里您显式地将类加载器用于列表的泛型类型。我遇到了同样的问题,我使用了bundle而不是parcleable
intent.setExtrasClassLoader(getClassLoader());
/* Send optional extras */
Bundle bundle = new Bundle();
bundle.putParcelable("object", mObject);
bundle.putString("stringVal", stringVal);
intent.putExtra("bundle",bundle);
在我的intent类中,我使用它来检索值:
Bundle oldBundle = intent.getBundleExtra("bundle");
ResultReceiver receiver = oldBundle.getParcelable("object");
String stringVal = oldBundle.getString("stringVal");
intent.setExtrasClassLoader(getClassLoader());
希望它对某些人有所帮助。如果自定义视图子类划分不正确,则可能会出现此错误 假设您正在子类化,并且希望将保存的状态添加到
onSaveInstanceState()
中的超级状态
Parcelable样板文件的不正确实现(从另一个类或模板复制)如下所示:
static class State extends BaseSavedState {
Bundle stateBundle;
//incorrect as super state uses ClassLoaderCreator
public static final Creator<State> CREATOR = new Creator<State>() {
public State createFromParcel(Parcel in) {
return new State(in);
}
public State[] newArray(int size) {
return new State[size];
}
};
State(Parcel source) {
super(source);
this.stateBundle = source.readBundle(getClass().getClassLoader());
}
State(Parcelable superState) {
super(superState);
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeBundle(stateBundle);
}
}
请注意,扩展android.support.v4.view.AbsSavedState
可能比BaseSavedState
或android.view.AbsSavedState
更好,因为它允许您将类加载器传递给超类:
SavedState(Parcel source, ClassLoader classLoader) {
super(source, classLoader); //available in android.support.v4.view.AbsSavedState
this.stateBundle = source.readBundle(classLoader);
}
这与我的答案基本相同。
MyClass.class
和getClass()
之间没有区别,它们都返回相同的类对象,因为在MyClass中调用了getClass()
。此外,您可以在这里使用任何类,只要它是一个自定义类,而不是框架提供的类。我没有说您不正确,只是这种形式可能更合适。也可以考虑,当你静态地引用类时,对<代码> GETCARCH()的方法调用是不必要的。在我的例子中,它不起作用。使用类加载器。我在不同的上下文中得到这个错误——在包含可分组的包上调用<代码>捆绑。当针对相关代码运行单个测试类时,它通过了,但运行整个测试套件会导致BadParcelableException
。“修复”是在bundle.keySet()
之前执行bundle.setClassloader(MyClass.class.getClassLoader())
。你好,David Rawson,非常感谢你的回答。这正是我对extended BottomNavigationView的看法。为什么这种情况没有100%发生?我在一些用户设备上得到了这一点,但无法在我的终端上复制。
SavedState(Parcel source, ClassLoader classLoader) {
super(source, classLoader); //available in android.support.v4.view.AbsSavedState
this.stateBundle = source.readBundle(classLoader);
}