扩展实现 Parcelable 的类

Posted

技术标签:

【中文标题】扩展实现 Parcelable 的类【英文标题】:Extending a class that implements Parcelable 【发布时间】:2012-06-06 04:09:58 【问题描述】:

我有一个类,我们称之为 A 类,它实现了 Parcelable。

我有第二个类,我们称它为 B 类,它扩展了 A 类。

我的问题是:

如何将 B 类的成员变量写入 Parcel,然后将其父类(即:A 类)的成员变量写入 Parcel(并随后读入)?

不需要重写 A 类的 Parcel 代码有什么妙招吗?还是只需要重写A类的Parcel代码,为B类的成员变量添加额外的代码?

【问题讨论】:

【参考方案1】:

如何将B类的成员变量写入Parcel,然后将其父类(即:A类)的成员变量写入Parcel

B 类从 A 类覆盖 writeToParcel(),链接到超类并将其自己的对象添加到 Parcel

(然后读入)?

B 类实现 public static final Parcelable.Creator<MyParcelable> CREATOR 的方式可以让两个类都读取它们的内容。如果您采用在 B 类上创建一个以 Parcel 作为构造函数参数的构造函数的方法,只需链接到超类构造函数(让 A 类完成工作),然后读取 B 类的数据。

关键是要以相同的顺序执行它们。如果你打算让A类先读取它的数据,那么A类必须先写它的数据。

不需要重写 A 类的 Parcel 代码有什么妙招吗?

继承和链接到超类。

【讨论】:

如何调用超类的构造函数? @CommonsWare 好的,所以我添加了超级(包裹);我的 B 类构造函数中的行;我现在如何确保以书面形式向包裹调用超类? @Jethro: 在子类的writeToParcel() 方法中调用super.writeToParcel() @CommonsWare 感谢您的建议!让我朝着正确的方向前进:D【参考方案2】:

加个例子,标注的答案确实是正确的,但是更直观的东西似乎更适合这种情况:

这将是晚餐班:

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 是关键。

【讨论】:

【参考方案3】:

这有点复杂,但诀窍是使用Reflection 获取子类成员的类型并对成员进行排序,以便您可以使用正确的类型以相同的确切顺序读取和写入数据。

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

所以现在你可以通过简单地扩展这个类来使任何类都可以打包。

【讨论】:

Android 中引入了 Parcelable 概念,以避免序列化过程中的反射。如果您要进行反射,那么您可以简单地实现 Serializable 标记接口。

以上是关于扩展实现 Parcelable 的类的主要内容,如果未能解决你的问题,请参考以下文章

Java Serializable vs Android Parcelable

Parcelable和Serializable的区别

Parcelable和Serializable的区别

Parcelable和Serializable的区别

Android -- 每日一问:Parcelable 和 Serializable 有什么用,它们有什么差别?

如何写Parcelable()一个实现Serializable的类型的字段