カスタムビューを間違ってサブクラス化すると、このエラーが発生する可能性があります。
BottomNavigationView
をサブクラス化し、onSaveInstanceState()
のスーパーステートに保存済み状態を追加するとします。
(他のクラスやテンプレートからコピー)Parcelableの決まり文句の間違った実装は次のようになります。BottomNavigationView
からスーパーステートは、クラスローダを必要とする
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);
}
}
これは動作しないでしょう。代わりに、あなたは慎重にBottomNavigationView
からSavedState
クラスを検査し、正しいClassLoaderCreator
ではなくCreator
を使用する必要があります。それはあなたがクラスローダを渡すことができるようになりますので、android.support.v4.view.AbsSavedState
を延びるBaseSavedState
またはandroid.view.AbsSavedState
より良い選択であってもよいこと
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);
}
}
注意をスーパークラス:
SavedState(Parcel source, ClassLoader classLoader) {
super(source, classLoader); //available in android.support.v4.view.AbsSavedState
this.stateBundle = source.readBundle(classLoader);
}
このエラーは別のコンテキストで発生しました。つまり、Parcelableを含むバンドルで 'bundle.keySet()'を呼び出しました。問題のコードに対して個々のテストクラスを実行すると、そのクラスは合格しましたが、テストスイート全体を実行すると 'BadParcelableException'が発生しました。 "修正"は 'bundle.keySet()'の前に 'bundle.setClassloader(MyClass.class.getClassLoader())'を実行することでした。 –