通过捆绑检索可包裹对象是否总是创建新副本? [英] Does retrieving a parcelable object through bundle always create new copy?

查看:97
本文介绍了通过捆绑检索可包裹对象是否总是创建新副本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过在创建片段时将其添加到捆绑中来将可包裹对象传递到片段。在onc实例中,对该包裹对象的修改反映了原始对象的修改,而在另一种情况下则没有。我对此行为感到困惑。
直到现在我已经假设通过捆绑包检索包裹的对象总是创建新对象[不确定是浅拷贝还是深拷贝]。

I'm passing a parcelable object to a fragment by adding into a bundle while creating the fragment. In onc instance modification to this parcelled object reflects modification in original object and in another case it is not. I'm a little baffled by this behaviour. Till now I have assumed retrieving a parcelled objects through a bundle always create new object[no sure whether it's shallow copy or deep copy].

请有人说明可打包的行为。

Someone please clarify parcelable behaviour.

推荐答案

我正在努力解决类似的问题。乍一看,似乎总是从包裹的对象中获得新的深层副本。此外,甚至还有一些 StackOverflow答案,建议使用 Parcelable 接口克隆对象。所有这些只会增加对该主题的困惑。

I was struggling with a similar issue. At the first glance it seems that we always obtain a new deep copy from the parcelled objects. Moreover, there are even some StackOverflow answers which suggest to use Parcelable interface to clone objects. All this just increases confusion regarding the subject.

以下是经过大量搜索和搜索后发现的内容:

Here is what I've found after a lot of searching and googling:


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

  • Take a closer look at the official Parcel documentation. Here is the important quote:

Parcel的一个不寻常功能是可以读取和写入有效
个对象。对于这些对象,不会写入
对象的实际内容,而是会写入引用该对象的特殊标记。
从包裹中读取对象时,您没有获得该对象的新
实例
,而是在
上完全相同的对象上操作的句柄

An unusual feature of Parcel is the ability to read and write active objects. For these objects the actual contents of the object is not written, rather a special token referencing the object is written. When reading the object back from the Parcel, you do not get a new instance of the object, but rather a handle that operates on the exact same object that was originally written.

好,如您所见,在取消包裹过程中,有一些特殊的对象没有被复制。但这仍然有些混乱。这是否意味着我们对防止垃圾回收的原始对象有了另一个强烈的引用?此类对象的用例是什么?

Ok, as you can see, there are some special objects that are not being copyed during unparceling. But this is still a bit confusing. Does it mean we have another strong reference to the original object which prevents its garbage collection? And what are the use-cases for such objects?


  • 为回答上述问题,我决定浏览Android 源代码。我正在寻找的方法是 readStrongBinder writeStrongBinder ,根据文档,当包裹已发送/接收。而且我想我在 ResultReceiver.java 类。这是有趣的行:

  • To answer the aforementioned questions I decided to look through the Android source code. The methods I was looking for are readStrongBinder and writeStrongBinder which according to the docs do not cause a new object creation when the parcels are sent/received. And I think I found the desired answer in the ResultReceiver.java class. Here is the interesting line:

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

要了解此行的实际作用,我们应该去官方 AIDL文档。这是最重要的部分:

To understand what is this line actually doing we should go to the official AIDL documentation. Here are the most important parts:


调用类必须采取的步骤带有AIDL的
远程接口:

...

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

The steps a calling class must take to call a remote interface defined with AIDL:
...
5. In your implementation of onServiceConnected(), you will receive an IBinder instance (called service). Call YourInterfaceName.Stub.asInterface((IBinder)service) to cast the returned parameter to YourInterface type.

有关调用IPC服务的一些评论:

A few comments on calling an IPC service:

对象是跨进程的引用计数

因此,我们将所有内容放在一起:

So let's put all things together:


  1. 可以提取已打包的对象而无需涉及深度复制过程。

  2. 如果使用 readStrongBinder 方法读取包裹的对象,则不会创建新实例。我们只是获得对原始对象的新引用,并且该引用可以防止其解除分配。

  3. 要了解在收到包裹后是否将对象深复制,我们应该仔细研究一下在具体的 Parcelable 接口实现中。

  4. Android文档可能确实令人困惑,并且可能需要大量时间才能正确理解它。

  1. The parcelled objects can be extracted without involving deep copy process.
  2. If the parcelled objects are read using readStrongBinder method no new instances are being created. We just objtain a new reference to the original object and this reference can prevent its dealllocation.
  3. To know whether our object will be deep copyed after the parcel has been received we should take a closer look at the concrete Parcelable interface implementation.
  4. Android documentation can be really confusing and it may take a lot of time to understand it correctly.

希望此信息对您有所帮助。

Hope this info will help you.

如果您想阅读一个真实的例子,关于 Parcelable 对象的困惑会导致严重的问题,请检查删除我的博客帖子

If you want to read about a real-world example when the confusion regarding Parcelable objects can cause serious problems check out my blog post.

这篇关于通过捆绑检索可包裹对象是否总是创建新副本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆