【问题标题】:readFromParcel() method in Parcelable interfaceParcelable 接口中的 readFromParcel() 方法
【发布时间】:2014-07-21 15:10:25
【问题描述】:

我对服务创建期间的编组有一个简单的疑问。当Parcelable接口中声明了writeToParcel()方法并在生成的stub中调用时(如果aidl方法参数声明为in),为什么Parcelable接口中没有readFromParcel()声明(对于@987654327 @ 参数)?

我可以创建自己的readFromParcel(),但根据我的理解,如果生成的存根想要调用它,Parcelable 接口中应该有一个覆盖的readFromParcel() 声明。但是Parcelable interface 的文档没有显示任何readFromParcel() 方法的迹象。为什么会这样?它是否包含在以前的 API 版本中,后来又被删除了?请解释!

如果 createFromParcel() 与 readFromParcel() 都尝试读取可打包对象并使用其中的数据填充成员字段,那么两者有何不同?

【问题讨论】:

  • readFromParcel 需要一个预先创建的对象,而createFromParcel 直接从包裹中返回一个新实例化的对象。这是因为当Parcelable 类型的实例用作outinout 参数时,从概念上讲,Binder 子系统会先创建一个空对象,然后在返回响应时将其填充为readFromParcel。跨度>

标签: android android-service parcelable aidl


【解决方案1】:

这是因为您在 AIDL 中将该类型的参数声明为“inout”。

从方法返回时,生成的 AIDL 代理将调用 readFromParcel() 来更新参数值(由“inout”限定符定义)。

【讨论】:

  • 这个问题可能措辞不正确,但我相信这回答正确。界面中没有readFromParcel 可能是因为不是每个人都需要他们的Parcelableoutinout 参数。这可以通过使 Parcelable 成为一个抽象类来解决(或者如果 Android 迁移到 Java 8,使用默认方法)。
【解决方案2】:

createFromParcel 正是它听起来的样子。创建已写入 parcel 的可包裹对象/类的新实例:Parcelable.writeToParcel()。这是一件好事,因为它有助于防止内存泄漏,因为您不会保留对另一个可能已经或可能没有被破坏的类的对象的引用

【讨论】:

  • readFromParcel 怎么样?为什么它作为生成的存根的一部分被调用?有什么见解吗?
  • 通常你从构造函数中调用它。我不确定我是否理解你的问题
【解决方案3】:

来自Parcelable interface的文档:

 public class MyParcelable implements Parcelable {
 private int mData;

 public int describeContents() {
     return 0;
 }

 public void writeToParcel(Parcel out, int flags) {
     out.writeInt(mData);
 }

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

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

 private MyParcelable(Parcel in) {
     mData = in.readInt();
 }
}

当实现 Parcelable 接口的类的对象被写入 Parcel 时,writeToParcel(...) 被调用。

当要使用 Parcel 创建此类的对象时,将调用 CREATOR.createFromParcel(Parcel in)。从那里开始,该类如何从 Parcel 创建其实例取决于该类的开发人员。在上面的例子中,构造函数private MyParcelable(Parcel in)是从createFromParcel(...)方法中调用的。

通常,许多开发人员在他们的实现中定义一个readFromParcel(Parcel in) 方法并从构造函数中调用它:

 private MyParcelable(Parcel in) {
     readFromParcel(in);
 }

 private void readFromParcel(Parcel in) {
     mData = in.readInt();
 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-17
    • 2018-02-01
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-12
    • 1970-01-01
    相关资源
    最近更新 更多