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 接口 - 冲突