Parcelable inheritance: abstract class - Which CREATOR?
android, inheritance, java, parcelable
Solution
I used Vincent Mimoun-Prat's parcelable architecture from this post: Parcelable and inheritance in Android and ran into the same typed list problem about having to specify an impossible abstract CREATOR.
Searching in Parcel's JavaDoc I found the method writeList(List val) that internally uses writeValue(Object) method for each object of the list and therefore calling `writeToParcel()` from subclasses (B and C from an A list). To unmarshall the list use its counterpart readList (List outVal, ClassLoader loader) where `A ClassLoader` has to be passed or an `android.os.BadParcelableException` is thrown, at least in my case.
Class containing A elements list should be something like this:
public class AContainer implements Parcelable {
//Other AContainer fields
List<A> elements = new ArrayList<>();
//Other AContainer fields
static final Parcelable.Creator<AContainer> CREATOR = new Parcelable.Creator<AContainer>() {
@Override
public AContainer createFromParcel(Parcel source) {
return new AContainer(source);
}
@Override
public AContainer[] newArray(int size) {
return new AContainer[size];
}
};
public AContainer() {
}
protected AContainer(Parcel source) {
//read other AContainer fields
source.readList(elements, A.class.getClassLoader());
//read other AContainer fields
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
//write other AContainer fields
dest.writeList(elements);
//write other AContainer fields
}
}
Using these methods may be a bit slower than `readTypedList()` and `writeTypedList()` but specific data from B and C subclasses is also "parcelled" and not only the fields from A abstract superclass (It will be impossible being abstract). You recover the right instances from B and C.
Problem
I have an abstract class `A` which implements Parcelable. I have a class `B` and a class `C` who both extend `A`. How can I make them parcelable? Of cause I could chain it and provide a `CREATOR` both in `A` and `B` like suggested in many posts. But since I have other Objects who store the `A-B-C` classes and implement Parcelable themselfes, that approach seems not to be working because when I want to pass an ArrayList of `A` I would have to use the `CREATOR` in the typed list by ``` ArrayList<A> elements = new ArrayList<>(); in.readTypedList(elements , B.CREATOR); // B.CREATOR? C.CREATOR??? ``` Which obviously makes no sense. So how can I properly make A Parcelable? I.e I want to make this class Parcelable so I can refer to A in a common way. A) ``` public abstract class A implements Parcelable { final String globalVar; public A(String globalVar) { this.globalVar = globalVar; } } ``` B) ``` public class B extends A { String bVar; public B(String global, String bVar) { super(global); this.bVar = bVar; } private B(Parcel in) { super(in.readString()); this.bVar = in.readString(); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(bVar); } } ``` C) ``` public class C extends A { String cVar; public C(String global, String cVar) { super(global); this.cVar = cVar; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(cVar); } } ```