是否可以对包含扩展相同基类的不同对象的列表进行parcel / deparcel?

时间:2015-10-07 18:26:40

标签: java android parcelable parcel

假设我有一个基本的抽象类(或接口),名为" Base"以及几个扩展它的具体类,如Concrete1,Concrete2,Concrete3。现在,我有另一个包含" Base"列表的Container类。对象:

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字段实现parceling并在deparceling之后具有相同类型的Concrete1,Concrete2等对象的列表?怎么样?

1 个答案:

答案 0 :(得分:0)

我使用以下方法。

  1. 确保Base实施Parcelable
  2. describeContents方法放入Base
  3. abstract void write2(Parcel p);中添加方法Base并在每个具体类中覆盖它。
  4. 在每个具体类中放置一个方法static Base create2(Parcel p)。这应该与write2相反。
  5. abstract int typeNumber()中编写一个抽象方法Base并在每个具体子类中覆盖它(每个子类应该返回一个不同的值。我使用静态最终字段CONCRETE1CONCRETE2 ,...我留在Base)。
  6. 然后,您可以将以下内容添加到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);
    

    此方法不要求将任何类的名称写入Parcel(它会写入int值),不需要使用反射找到CREATOR个字段,并且不需要ClassLoader