通过包检索一个parcelable对象总是创build新的副本?

我通过在创build片段的同时添加一个可分段的对象到一个片段。 在onc实例中,对这个包裹对象的修改反映了对原始对象的修改,而在另一种情况下则不是。 我对这种行为有点困惑。 直到现在,我已经假设通过一个包检索一个包裹的对象总是创build一个新的对象[不知道是浅层复制还是深层复制]。

有人请澄清可说的行为。

Solutions Collecting From Web of "通过包检索一个parcelable对象总是创build新的副本?"

我正在为类似的问题挣扎。 乍一看,我们总是从包裹的物体上获得新的深层复制。 此外,甚至有一些 StackOverflow的答案build议使用Parcelable接口克隆对象。 所有这些只会增加对这个问题的困惑。

这是我经过大量search和search后发现的:

  • 仔细查看官方的Parcel 文档 。 这里是重要的报价:

Parcel的一个不寻常的function是能够读写活动对象。 对于这些对象,不写入对象的实际内容,而是写入引用该对象的特殊标记。 从Parcel中读取对象时, 不会获得对象的新实例 ,而是一个对原来写入的同一个对象进行操作的句柄。

好的,正如你所看到的那样,有些特殊的对象在不encryption的情况下不会被拷贝。 但是这仍然有点混乱。 这是否意味着我们有另一个强大的参考,以防止其垃圾收集的原始对象? 那么这些对象有什么用途呢?

  • 为了回答上述问题,我决定查看Android 源代码 。 我正在查找的方法是readStrongBinderwriteStrongBinder ,根据文档不会在发送/接收包裹时导致创build新的对象。 我想我在ResultReceiver.java类中find了所需的答案。 这是有趣的一行:

     mReceiver = IResultReceiver.Stub.asInterface(in.readStrongBinder()); 

    为了理解这条线究竟在做什么,我们应该去官方的AIDL文档 。 这里是最重要的部分:

调用类必须采用的步骤来调用使用AIDL定义的远程接口:

5.在实现onServiceConnected()时,您将收到一个IBinder实例(称为service)。 调用YourInterfaceName.Stub.asInterface((IBinder)服务)将返回的参数强制转换为YourInterfacetypes。

关于调用IPC服务的几点意见:

对象是跨进程的引用计数

所以让我们把所有的东西放在一起:

  1. 包裹对象可以被提取而不涉及深度复制过程。
  2. 如果使用readStrongBinder方法读取包裹对象,则不会创build新的实例。 我们只是获得对原始对象的新引用,并且这个引用可以防止它的分配。
  3. 要知道在收到包裹后我们的对象是否被深度拷贝,我们应该仔细看看具体的Parcelable接口的实现。
  4. Android文档可能会让人感到困惑,并且可能需要很长时间才能正确理解。

希望这个信息将帮助你。

如果您想了解关于Parcelable对象的混淆可能导致严重问题的真实示例,请查看我的博客文章 。