Flo*_*low 49 android marshalling unmarshalling parcel
给定一个自定义类org.example.app.MyClass implements Parcelable,我想写List<MyClass>一个包.我做了编组
List<MyClass> myclassList = ...
parcel.writeList(myclassList);
Run Code Online (Sandbox Code Playgroud)
每当我试图解散课程时
List<MyClass> myclassList = new ArrayList<MyClass>();
parcel.readList(myclassList, null);
Run Code Online (Sandbox Code Playgroud)
有一个"BadParcelableException: ClassNotFoundException when unmarshalling org.example.app.MyClass"例外.
这有什么不对?为什么找不到课程?
Flo*_*low 103
不要使用null作为ClassLoader参数提供的框架类加载器来解组自定义类(即由应用程序提供而不是由Android框架提供的类).使用应用程序类加载器:
parcel.readList(myclassList, getClass().getClassLoader());
Run Code Online (Sandbox Code Playgroud)
每当一个Parcel.read*()方法也有一个ClassLoader作为参数(例如Parcel.readList(List outVal, ClassLoader loader))并且你想从a读取一个应用程序类时Parcel,使用可以检索的应用程序类加载器getClass().getClassLoader().
背景: Android附带两个类加载器:系统类加载器,它能够加载所有系统类,但是应用程序提供的系统类; 和应用程序类加载器,它将系统类加载器设置为其父类,因此能够加载所有类.如果将null作为类加载器,将使用框架类加载器,从而导致ClassNotFoundException.Parcel.readParcelableCreator()
感谢alexanderblom提供的提示让我走上正轨.
Tan*_*ien 18
我相信更正确的形式是:
List<MyClass> myclassList = new ArrayList<MyClass>();
parcel.readList(myclassList, MyClass.class.getClassLoader());
Run Code Online (Sandbox Code Playgroud)
因为在这里您明确使用List的泛型类型的类加载器.
我遇到了同样的问题,我使用了 bundle 而不是 parcleable
intent.setExtrasClassLoader(getClassLoader());
/* Send optional extras */
Bundle bundle = new Bundle();
bundle.putParcelable("object", mObject);
bundle.putString("stringVal", stringVal);
intent.putExtra("bundle",bundle);
Run Code Online (Sandbox Code Playgroud)
在我的意图类中,我用它来检索值:
Bundle oldBundle = intent.getBundleExtra("bundle");
ResultReceiver receiver = oldBundle.getParcelable("object");
String stringVal = oldBundle.getString("stringVal");
intent.setExtrasClassLoader(getClassLoader());
Run Code Online (Sandbox Code Playgroud)
希望对一些人有所帮助。
如果您错误地将自定义视图子类化,您可能会收到此错误。
假设您正在创建子类,BottomNavigationView并且想要将保存的状态添加到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);
}
}
Run Code Online (Sandbox Code Playgroud)
这不会起作用,因为来自的超状态BottomNavigationView需要类加载器。相反,您应该仔细检查SavedState类BottomNavigationView并使用正确的ClassLoaderCreator而不是Creator:
static class State extends AbsSavedState {
Bundle stateBundle;
public static final Creator<State> CREATOR = new ClassLoaderCreator<State>() {
public State createFromParcel(Parcel in, ClassLoader classLoader) {
return new State(in, classLoader);
}
@Override
public State createFromParcel(Parcel source) {
return new State(source, null);
}
public State[] newArray(int size) {
return new State[size];
}
};
State(Parcel source, ClassLoader classLoader) {
super(source, classLoader);
this.stateBundle = source.readBundle(classLoader);
}
State(Parcelable superState) {
super(superState);
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeBundle(stateBundle);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,扩展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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
32890 次 |
| 最近记录: |