Как написать Parcelable
для дерева, как структура, которая имеет Base
класс с двумя реализациями, один в Node
типа, а другой Container
типа, который содержит список Base
типов.Android Parcelable с деревом родовых типов
Извините за массу кода, приведенного ниже. Основная структура данных небольшая, но в нее включена моя текущая реализация Parcelable
, которая не работает.
Я попытался добавить байт в базу writeToParcel
, который сигнализирует, какой тип создавать, когда он отделяется, но, похоже, не работает.
Проблема в том, что я получаю разные данные обратно при отправке объекта Base
, который содержит глубокое дерево Container
объектов.
Любые идеи о том, что я делаю неправильно?
Также будут оценены любые идеи о том, как реализовать модульные тесты для Parcelable
.
Базовый класс
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];
}
};
}
Контейнер класса
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];
}
};
}