Bạn có thể gặp lỗi này nếu bạn phân lớp Chế độ xem tùy chỉnh không chính xác.
Giả sử bạn đang phân lớp BottomNavigationView
và bạn muốn thêm trạng thái đã lưu vào superstate trong onSaveInstanceState()
.
An thực hiện không chính xác của các soạn sẵn Parcelable (sao chép từ một lớp hay một bản mẫu) sẽ trông như thế này:
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);
}
}
Điều này sẽ không làm việc như các superstate từ BottomNavigationView
đòi hỏi một classloader. Thay vào đó bạn nên cẩn thận kiểm tra lớp SavedState
từ BottomNavigationView
và sử dụng đúng ClassLoaderCreator
hơn 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);
}
}
Lưu ý rằng việc mở rộng android.support.v4.view.AbsSavedState
có thể là một lựa chọn tốt hơn so với BaseSavedState
hoặc android.view.AbsSavedState
vì nó sẽ cho phép bạn để vượt qua một bộ nạp lớp để siêu lớp:
SavedState(Parcel source, ClassLoader classLoader) {
super(source, classLoader); //available in android.support.v4.view.AbsSavedState
this.stateBundle = source.readBundle(classLoader);
}
Nguồn
2018-01-23 23:19:43
Tôi nhận được lỗi này trong một ngữ cảnh khác - gọi 'bundle.keySet()' trên một gói có chứa Parcelable. Khi chạy một lớp thử nghiệm riêng lẻ đối với mã được đề cập, nó đã trôi qua, nhưng chạy toàn bộ bộ kiểm thử dẫn đến 'BadParcelableException'. "Fix" là để thực hiện 'bundle.setClassloader (MyClass.class.getClassLoader())' trước 'bundle.keySet()'. –