是否可以 parcel/deparcel 扩展相同基础 class 的不同对象的列表?
Is it possible to parcel/deparcel a list of different objects that extend same base class?
假设我有一个基本抽象 class(或接口),称为 "Base" 和几个扩展它的具体 class,如 Concrete1、Concrete2、Concrete3。现在,我有另一个容器 class,其中包含 "Base" 个对象的列表:
public class Container implements Parcelable {
...
private List<Base> baseList;
}
假设我想将几个具体对象放入 baseList:
baseList.add(new Concrete1());
baseList.add(new Concrete2());
baseList.add(new Concrete3());
baseList.add(new Concrete2());
是否可以对baseList字段进行分块,分块后得到Concrete1、Concrete2等同类型的对象列表?怎么样?
我使用以下方法。
- 确保
Base
实现了 Parcelable
。
- 在
Base
中放置一个describeContents
方法。
- 在
Base
中放入方法abstract void write2(Parcel p);
方法并在每个具体class中重写它。
- 在每个具体class中放一个方法
static Base create2(Parcel p)
。这应该是 write2
. 的反面
- 在
Base
中写一个抽象方法abstract int typeNumber()
并在每个具体子class中覆盖它(每个子class应该return一个不同的值。我使用静态最终字段 CONCRETE1
、CONCRETE2
、...我保留在 Base
).
然后你可以在Base
中添加以下内容:
@Override
public final void writeToParcel(Parcel p, int flags) {
p.writeInt(typeNumber());
write2(p);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
@Override
public Base createFromParcel(Parcel p) {
switch (p.readInt()) {
case CONCRETE1: return Concrete1.create2(p);
case CONCRETE2: return Concrete2.create2(p);
// etc
default: throw new AssertionError();
}
}
@Override
public Base[] newArray(int size) {
return new Base[size];
}
}
然后你可以写一个 List
使用
parcel.writeTypedList(baseList);
并使用
读回
List<Base> list = new ArrayList<Base>();
parcel.readTypedList(list, Base.CREATOR);
此方法不需要将任何 class 的名称写入 Parcel
(而是写入 int
值),不需要 CREATOR
字段可以使用反射找到,并且不需要 ClassLoader
.
假设我有一个基本抽象 class(或接口),称为 "Base" 和几个扩展它的具体 class,如 Concrete1、Concrete2、Concrete3。现在,我有另一个容器 class,其中包含 "Base" 个对象的列表:
public class Container implements Parcelable {
...
private List<Base> baseList;
}
假设我想将几个具体对象放入 baseList:
baseList.add(new Concrete1());
baseList.add(new Concrete2());
baseList.add(new Concrete3());
baseList.add(new Concrete2());
是否可以对baseList字段进行分块,分块后得到Concrete1、Concrete2等同类型的对象列表?怎么样?
我使用以下方法。
- 确保
Base
实现了Parcelable
。 - 在
Base
中放置一个describeContents
方法。 - 在
Base
中放入方法abstract void write2(Parcel p);
方法并在每个具体class中重写它。 - 在每个具体class中放一个方法
static Base create2(Parcel p)
。这应该是write2
. 的反面
- 在
Base
中写一个抽象方法abstract int typeNumber()
并在每个具体子class中覆盖它(每个子class应该return一个不同的值。我使用静态最终字段CONCRETE1
、CONCRETE2
、...我保留在Base
).
然后你可以在Base
中添加以下内容:
@Override
public final void writeToParcel(Parcel p, int flags) {
p.writeInt(typeNumber());
write2(p);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
@Override
public Base createFromParcel(Parcel p) {
switch (p.readInt()) {
case CONCRETE1: return Concrete1.create2(p);
case CONCRETE2: return Concrete2.create2(p);
// etc
default: throw new AssertionError();
}
}
@Override
public Base[] newArray(int size) {
return new Base[size];
}
}
然后你可以写一个 List
使用
parcel.writeTypedList(baseList);
并使用
读回List<Base> list = new ArrayList<Base>();
parcel.readTypedList(list, Base.CREATOR);
此方法不需要将任何 class 的名称写入 Parcel
(而是写入 int
值),不需要 CREATOR
字段可以使用反射找到,并且不需要 ClassLoader
.