Android 中的 Parcelable 和继承

Posted

技术标签:

【中文标题】Android 中的 Parcelable 和继承【英文标题】:Parcelable and inheritance in Android 【发布时间】:2011-05-02 06:25:06 【问题描述】:

我得到了一个 Parcelable 的实现,它为一个不涉及继承的单个类工作。当涉及到继承时,我很难找出实现接口的最佳方式。假设我得到了这个:

public abstract class A 
    private int a;
    protected A(int a)  this.a = a; 


public class B extends A 
    private int b;
    public B(int a, int b)  super(a); this.b = b; 

问题是,这是为 B 实现 Parcelable 接口的推荐方法(在 A 中?在它们两个中?如何?)

【问题讨论】:

自从您打开此问题后,您是否找到了比这更好的解决方案? 不,我认为我下面提出的解决方案相当简单,对我来说就像一个魅力。 它是否适用于多态使用,例如具有 B 对象的 A 类型数组? 不知道,试试看,然后在这里发布你的结果。 结帐:***.com/a/10841502/1052261 【参考方案1】:

这是我最好的解决方案,我很高兴收到对此有想法的人的意见。

public abstract class A implements Parcelable 
    private int a;

    protected A(int a) 
        this.a = a;
    

    public void writeToParcel(Parcel out, int flags) 
        out.writeInt(a);
    

    protected A(Parcel in) 
        a = in.readInt();
    


public class B extends A 
    private int b;

    public B(int a, int b) 
        super(a);
        this.b = b;
    

    public static final Parcelable.Creator<B> CREATOR = new Parcelable.Creator<B>() 
        public B createFromParcel(Parcel in) 
            return new B(in);
        

        public B[] newArray(int size) 
            return new B[size];
        
    ;

    public int describeContents() 
        return 0;
    

    public void writeToParcel(Parcel out, int flags) 
        super.writeToParcel(out, flags);
        out.writeInt(b);
    

    private B(Parcel in) 
        super(in);
        b = in.readInt();
    

【讨论】:

我们是否也需要在 B 类(子类)中实现 Parcelable? @jsmith 不,我没有,如果你试试就告诉我。 @CheokYanCheng 不,因为A实现了它,这意味着B也实现了(无需在B声明中重复implements Parcelable @MarvinLabs 有什么理由不需要提供 describeContents 实现吗? (我可以理解为什么 A 不提供 CREATOR,因为它是抽象的并且无法创建自身的实例)另外,我可以知道测试一切是否正确的正确方法吗?能够从 Bundle 中保存和检索足够吗? 我试图通过 AIDL 传递 A,但它不起作用。 B 丢失。解决方法是将对象放在一个 Bundle 中并通过 AIDL 传递该包。您只需要确保在另一端使用正确的类加载器。【参考方案2】:

这是我的变种。我认为这很好,因为它非常清楚地显示了虚拟读写方法之间的对称性。

旁注:我认为 Google 在设计 Parcelable 界面方面做得非常糟糕。

public abstract class A implements Parcelable 
    private int a;

    protected A(int a) 
        this.a = a;
    

    public void writeToParcel(Parcel out, int flags) 
        out.writeInt(a);
    

    public void readFromParcel(Parcel in) 
        a = in.readInt();
    


public class B extends A 
    private int b;

    public B(int a, int b) 
        super(a);
        this.b = b;
    

    public static final Parcelable.Creator<B> CREATOR = new Parcelable.Creator<B>() 
        public B createFromParcel(Parcel in) 
            return new B(in);
        

        public B[] newArray(int size) 
            return new B[size];
        
    ;

    public int describeContents() 
        return 0;
    

    public void writeToParcel(Parcel out, int flags) 
        super.writeToParcel(out, flags);
        out.writeInt(b);
    

    public void readFromParcel(Parcel in) 
        super(in);
        b = in.readInt();
    

【讨论】:

如果你想打包一个列表会发生什么? createFromParcel()中,不应该是B b = new B(in);而不是B b = new B(); b(in);吗?后者(您当前的代码)不会编译,因为 b(in) 不是有效的方法或构造函数调用。【参考方案3】:

这是 A 类在现实世界中的实现,因为 B 类可能有多个具有除 int 之外的不同类型的对象

它使用反射来获取类型。然后使用排序函数对字段进行排序,以便读取和写入以相同的顺序发生。

https://github.com/awadalaa/android-Global-Parcelable

【讨论】:

Parcelable 被引入以避免使用反射 API,因为它很慢。您所做的是将慢速反射 API 与现代 Parcelable 解决方案相结合。这不是它的使用方式。

以上是关于Android 中的 Parcelable 和继承的主要内容,如果未能解决你的问题,请参考以下文章

Android中的Parcelable接口和Serializable用法和区别

——Parcelable接口的使用(跨进程,Intent传输)

从 Android 中的对象实现 Serializable 和 Parcelable 接口 - 冲突

Android Studio中如何创建AIDL

***Error关于为android中的类编写Parcelable

从Kotlin构造函数android中的Parcelable读取List列表