扩展一个实现Parcelable接口的类

15
我有一个实现了 Parcelable 接口的类,我们称其为类 A。
我有第二个类,我们称其为类 B,它继承自类 A。
我的问题是:
如何将类 B 的成员变量写入 Parcel,然后将其父类的 (即类 A 的) 成员变量写入 Parcel (并在之后读取它们)?
是否有一些巧妙的技巧可以不需要重写类 A 的 Parcel 代码?还是我只需要重写类 A 中的 Parcel 代码并为类 B 的成员变量添加额外的代码?
3个回答

24
如何将类B的成员变量写入Parcel并将其父类(即类A)的成员变量写入Parcel?
类B覆盖了类A的writeToParcel()方法,链接到超类并添加自己的对象到Parcel中。
(在之后)如何读取它们?
类B以这样的方式实现public static final Parcelable.Creator CREATOR,以便让两个类都可以读取它们的内容。如果采用在Class B上创建一个以Parcel为构造参数的构造函数的方法,只需链接到超类构造函数(让Class A完成其工作),然后读取Class B的数据即可。
关键在于以相同的顺序执行它们。如果您打算让Class A先读取其数据,则Class A必须先写入其数据。
有没有什么聪明的诀窍可以不需要重新编写Class A的Parcel代码?
继承并链接到超类。

如何调用父类的构造函数? - Andrew
@Andrew:和在任何Java类中一样:在你自己的构造函数中,将super(...)(其中...是你的参数列表,如果有的话)作为第一行。 - CommonsWare
@CommonsWare 好的,我已经在我的B类构造函数中添加了super(parcel);语句;现在我该如何确保在写入parcel时调用超类? - Jethro
1
@Jethro:在子类的writeToParcel()方法中调用super.writeToParcel() - CommonsWare
@CommonsWare 感谢您的建议!让我朝着正确的方向前进 :D - Jethro

4

添加一个例子,标记的答案确实正确,但对于这种情况,更直观的东西似乎更合适:

这将是超类:

public class BasePojo implements Parcelable {

    private String something;

    //what ever other constructor

    //getters and setters

    protected BasePojo(Parcel in) {
        something = in.readString();
    }

    public static final Creator<BasePojo> CREATOR = new Creator<BasePojo>() {
        @Override
        public BasePojo createFromParcel(Parcel in) {
            return new BasePojo(in);
        }

        @Override
        public BasePojo[] newArray(int size) {
            return new BasePojo[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(something);
    }

}

然后这将是子类:

public class ChildPojo extends BasePojo implements Parcelable {

    private int somethingElse;

    //what ever other constructor

    //getters and setters

    protected ChildPojo(Parcel in) {
        super(in);
        somethingElse = in.readInt();
    }

    public static final Creator<ChildPojo> CREATOR = new Creator<ChildPojo>() {
        @Override
        public ChildPojo createFromParcel(Parcel in) {
            return new ChildPojo(in);
        }

        @Override
        public ChildPojo[] newArray(int size) {
            return new ChildPojo[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        super.writeToParcel(parcel, i);
        parcel.writeInt(somethingElse);
    }

}

这个标记答案提供了一个非常好的解释,调用super是关键。

1

这有点复杂,但诀窍是使用反射获取子类成员的类型,并对成员进行排序,以便使用正确的类型按照相同的顺序读写数据。

我在这里为A类实现了解决方案:https://github.com/awadalaa/Android-Global-Parcelable

因此,现在您只需扩展此类就可以使任何类可被包裹。


4
为避免在序列化期间使用反射,Android引入了Parcelable概念。如果您要使用反射,则可以简单地实现Serializable标记接口。 - Sankar V

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接