Sie können diesen Fehler erhalten, wenn Sie eine benutzerdefinierte Ansicht falsch ableiten.
Angenommen, Sie bilden die Unterklasse BottomNavigationView
, und Sie möchten den gespeicherten Status zum Superzustand in onSaveInstanceState()
hinzufügen.
Eine falsche Implementierung des Parcel vorformulierten (von einer anderen Klasse oder einer Vorlage kopiert) würde wie folgt aussehen:
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);
}
}
Dies würde erfordert nicht funktionieren, da die Super von BottomNavigationView
einen Klassenlader. Stattdessen sollten Sie sorgfältig die SavedState
Klasse von BottomNavigationView
inspizieren und verwenden Sie den richtigen ClassLoaderCreator
statt 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);
}
}
Beachten Sie, dass android.support.v4.view.AbsSavedState
erstreckt, kann eine bessere Wahl sein als BaseSavedState
oder android.view.AbsSavedState
, da es Ihnen erlaubt, einen Klassenlader zu passieren die Oberklasse:
SavedState(Parcel source, ClassLoader classLoader) {
super(source, classLoader); //available in android.support.v4.view.AbsSavedState
this.stateBundle = source.readBundle(classLoader);
}
Ich habe diesen Fehler in einem anderen Kontext - aufrufen 'bundle.keySet()' auf einem Bündel, das ein Parcelable enthielt. Wenn eine einzelne Testklasse mit dem fraglichen Code ausgeführt wurde, wurde sie übergeben, aber das Ausführen der gesamten Testsuite führte zur "BadParcelableException". Das "Fix" war 'bundle.setClassloader (MyClass.class.getClassLoader())' vor 'bundle.keySet()'. –