我通过在创建片段时添加到捆绑包中来将可打包对象传递给片段。在一个实例中,对此包裹对象的修改反映了原始对象的修改,而在另一种情况下则不然。我对这种行为有点困惑。
到目前为止,我假设通过捆绑检索打包对象总是会创建新对象[不确定它是浅复制还是深复制]。
请有人澄清可分割的行为。
我正在为类似的问题而苦苦挣扎。乍一看,我们似乎总是从包裹的对象中获取新的深层副本。不仅如此,甚至还有some https://stackoverflow.com/questions/3773200/using-parcel-to-clone-an-object建议使用的 StackOverflow 答案Parcelable
克隆对象的接口。所有这些只会增加有关该主题的混乱。
以下是我经过大量搜索和谷歌搜索后发现的内容:
- 仔细看看官方
Parcel
文档 https://developer.android.com/reference/android/os/Parcel.html。这是重要的引用:
Parcel 的一个不寻常的特性是能够读写活动
对象。对于这些对象,对象的实际内容不是
写入,而不是写入引用该对象的特殊标记。
当从 Parcel 读回对象时,您没有得到新的
实例对象的,而是对对象进行操作的句柄
与最初编写的对象完全相同。
好的,正如您所看到的,有一些特殊对象在解包过程中没有被复制。但这仍然有点令人困惑。这是否意味着我们对原始对象有另一个强引用,从而阻止了其垃圾回收?这些对象的用例是什么?
-
为了回答上述问题,我决定研究一下 Android源代码 https://android.googlesource.com/platform/frameworks/base/+/android-3.2.4_r1/core/java/android/os。我正在寻找的方法是readStrongBinder
and writeStrongBinder
根据文档,在发送/接收包裹时不会导致创建新的对象。我想我在其中找到了想要的答案结果接收器.java https://android.googlesource.com/platform/frameworks/base/+/android-3.2.4_r1/core/java/android/os/ResultReceiver.java班级。这是有趣的一行:
mReceiver = IResultReceiver.Stub.asInterface(in.readStrongBinder());
要了解这条线实际上在做什么,我们应该去官方AIDL文档 https://developer.android.com/guide/components/aidl.html。以下是最重要的部分:
调用类调用定义的远程接口必须采取的步骤
使用 AIDL:
...
5. 在 onServiceConnected() 的实现中,您将收到一个
IBinder实例(称为服务)。称呼YourInterfaceName.Stub.asInterface((IBinder)service)来投射
返回参数为 YourInterface 类型。
关于调用IPC服务的几点评论:
对象是引用计数跨流程。
所以让我们把所有的东西放在一起:
- 可以提取包裹的对象,而无需涉及深复制过程。
- 如果使用读取包裹对象
readStrongBinder
方法没有创建新实例。我们只是获取对原始对象的新引用,并且该引用可以防止其释放。
- 要知道您的对象在收到包裹后是否会被深度复制,我们应该仔细看看具体的情况
Parcelable
接口实现。
- Android 文档可能真的很混乱,可能需要很多时间才能正确理解它。
希望这些信息对您有帮助。
如果您想了解一个现实世界的例子,当您遇到以下困惑时Parcelable
物体可能会导致严重的问题,看看我的博客文章 https://stanmots.blogspot.com/2016/10/androids-bad-company-intentservice.html.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)