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);
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With