parcelable继承:抽象类 - 哪个CREATOR?

时间:2015-02-17 17:47:08

标签: java android inheritance parcelable

我有一个抽象类A,它实现了Parcelable。

我有一个课程B和一个课程C,他们都延伸A。 我怎样才能使它们变得可以分辨?

我可以将其链接起来并在CREATORA中提供B,就像许多帖子中建议的那样。但由于我有其他对象存储A-B-C类并实现Parcelable自己,这种方法似乎不起作用,因为当我想传递A的ArrayList时,我将不得不使用{{1在

的类型列表中
CREATOR

这显然毫无意义。那么我怎样才能正确制作A Parcelable?

即我想让这个类Parcelable,所以我可以用一种常见的方式引用A.

A)

ArrayList<A> elements = new ArrayList<>();
in.readTypedList(elements , B.CREATOR); // B.CREATOR? C.CREATOR???

B)

public abstract class A implements Parcelable {

    final String globalVar;

    public A(String globalVar) {
        this.globalVar = globalVar;
    }
}

C)

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);
    }
}

2 个答案:

答案 0 :(得分:11)

我在这篇文章中使用了Vincent Mimoun-Prat的可分辨架构:Parcelable and inheritance in Android并遇到了关于必须指定一个不可能的抽象CREATOR的相同类型列表问题。

在Parcel的JavaDoc中搜索我发现方法writeList(List val)在内部对列表的每个对象使用writeValue(Object)方法,因此从子类调用writeToParcel()(B和C来自一个清单)。要解组列表,请使用其中必须传递A ClassLoader的对应readList (List outVal, ClassLoader loader)或者抛出android.os.BadParcelableException,至少在我的情况下。

包含A元素列表的类应该是这样的:

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
    }
}

使用这些方法可能比readTypedList()writeTypedList()慢一些,但来自B和C子类的特定数据也是&#34; parceled&#34;而且不仅仅是抽象超类中的字段(它不可能是抽象的)。您可以从B和C恢复正确的实例。

答案 1 :(得分:-2)

public class A implements Parcelable{

       public A(){

       }

       public A(Parcel in){
            super(in);
           // read from parcel
           // number = in.readInt() etc
       }

       @Оverride
       public int describeContents(){
           return 0;
       }

       @Override
       public void writeToParcel(Parcel dest, int flags) {
           super.writeToParcel(out, flags);
          // write to parcel
          // out.writeInt
       }
       public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
           public Student createFromParcel(Parcel in) {
               return new A(in); 
           }

           public A[] newArray(int size) {
               return new A[size];
           }
       };
   }

B和C还必须实现Parcelable