How to write Parcelable
for a tree like structure that has a Base
class with two implementations, one a Node
type and the other a Container
Type which contains a list of Base
types.
Sorry for the mass of code below. The basic data structure is small but I have in included my current Parcelable
implementation which is not working.
I have tried adding a byte in the base writeToParcel
which signals which type to create when unparceling but the does not seem to work.
The problem is I am getting different data back when I parcel a Base
object that contains a deep tree of Container
objects.
Any ideas on what I am doing wrong?
Also any ideas on how to implemented unit tests for Parcelable
s would be appreciated.
Base Class
public abstract class Base implements Parcelable {
public int val;
protected Base(final int val) {
this.val = val;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeByte((byte) (this instanceof NodeBase ? 0 : 1));
dest.writeInt(this.val);
}
protected Base(Parcel in) {
this.val = in.readInt();
}
public static final Creator<Base> CREATOR = new Creator<Base>() {
@Override
public Base createFromParcel(Parcel source) {
return source.readByte() == 0 ? new NodeBase(source) : new ContainerBase(source);
}
@Override
public Base[] newArray(int size) {
return new Base[size];
}
};
}
Node Class
public class NodeBase extends Base {
public final String name;
public NodeBase(final int val, final String name) {
super(val);
this.name = name;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(this.name);
}
protected NodeBase(Parcel in) {
super(in);
this.name = in.readString();
}
public static final Creator<NodeBase> CREATOR = new Creator<NodeBase>() {
@Override
public NodeBase createFromParcel(Parcel source) {
return new NodeBase(source);
}
@Override
public NodeBase[] newArray(int size) {
return new NodeBase[size];
}
};
}
Container Class
public class ContainerBase extends Base {
public final List<Base> baseList;
public ContainerBase(final int val, final List<Base> baseList) {
super(val);
this.baseList = baseList;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeTypedList(this.baseList);
dest.writeInt(this.val);
}
protected ContainerBase(Parcel in) {
super(in);
this.baseList = in.createTypedArrayList(Base.CREATOR);
this.val = in.readInt();
}
public static final Creator<ContainerBase> CREATOR = new Creator<ContainerBase>() {
@Override
public ContainerBase createFromParcel(Parcel source) {
return new ContainerBase(source);
}
@Override
public ContainerBase[] newArray(int size) {
return new ContainerBase[size];
}
};
}