【问题标题】:How to check if two Android binder proxy objects are equal?如何检查两个 Android binder 代理对象是否相等?
【发布时间】:2012-07-13 02:53:00
【问题描述】:

我有一个关于 Android 活页夹的问题。如果我理解正确,可以在进程之间传递 Binder。在服务端,有一个Binder对象(原始对象)。在客户端(在单独的进程中),有一个 BinderProxy 对象来处理 AIDL 数据编组。

我的问题是 - 你如何检查两个 BinderProxy 对象是否相等?我的意思是,它们在服务进程中引用相同的 Binder 对象。 我们可以使用 equals() 方法吗? BinderProxy 对象是否与原始 Binder 对象具有相同的内存地址?

谢谢!

编辑:

回应 David Wasser 的评论:

我为什么要这样做的原因解释起来有点复杂,但让我看看我能不能解释清楚--

远程服务提供了一个 AIDL API(客户端通过接收 onServiceConnected 中的 IBinder 来获得)。 AIDL API 包含两个方法——

IBinder getInterface(String interfaceName);

void releaseInterface(IBinder binder);

这个想法是客户端应用程序可以为不同接口的绑定器请求远程服务。接口实现的 dex 代码及其绑定器是动态加载到服务中的,并且事先不知道。该服务为客户端应用程序提供这 2 个 AIDL 方法,以根据接口名称访问那些动态加载的接口的绑定器。

假设有 App1 和 App2。每个都做'binder1 = getInterface(“SomeInterface1”);'并为该动态加载的接口“SomeInterface1”获取活页夹。使用后,应用程序通过说'releaseInterface(binder1);'释放接口绑定器以便服务可以卸载接口的 dex 代码并进行一些清理。

但是,除非App1 和App2 都释放了界面绑定器,否则无法卸载界面dex 代码。因此,在服务中,我为每个动态加载的活页夹维护一个引用计数。 (比如说一个 Map 键{Binder} ==> value{reference count})。当应用程序执行 getInterface() 时,我会增加引用计数。当它确实 releaseInterface(binder1) 时,我应该减少引用计数。但是,为此,我需要检查 binder1 是否等于 Map 中的 binder 键。

请注意,binder 已从服务(原始 binder 对象)传递到客户端应用程序(getInterface() 返回的 binder 代理)并再次返回到服务(作为 releaseInterface() 的参数 - 它仍然是代理,还是原版??)。

App1 和 App2 可以为相同的接口名称获取不同的绑定器对象(接口的不同实现)。这就是为什么,我使用活页夹来释放。

希望这不会太混乱!感谢您的帮助。

卡提克

【问题讨论】:

  • 确保 BinderProxy 对象具有与原始 Binder 对象不同的内存地址。 equals() 方法在 BinderProxy 中没有被覆盖,所以我假设你不能用它来比较。你想做什么?也许还有另一种方法可以解决这个问题。
  • 感谢您的快速回复!我已经编辑了我的问题,以包括检查两个活页夹相等的原因。
  • 我阅读了您的其他 cmets。在我的脑海中,我假设你正在服务中进行这种比较,你将拥有相同的 Binder 对象,因为代理对象在其他进程中。所以你应该可以使用equals()。但是,可以肯定的是,您为什么不拼凑一个小型测试程序,该程序完全按照您的描述进行。这应该很容易做到,并且会给你一个明确的答案。我总是更喜欢亲眼所见,而不是相信别人的话;-) 经验证据是最好的证据!
  • 是的,我认为你是对的。让我尝试使用equals()。如果不行,我可以用另一种方式解决这个问题:给每个App一个cookie值,让他们在释放binder的时候指定cookie值。但希望 equals() 能完成这项工作。感谢您的帮助!

标签: android android-binder


【解决方案1】:

据我所知,没有简单的解决方案。 BinderProxy 是 android.os.Binder 中的最后一个类。您可以找到来源here。一种解决方案可能是创建自己的扩展 Binder 的类并创建自己的实现以将 Binder 的实例存储在 BinderProxy 中或以其他方式存储。这很难,因为两个类都没有直接引用另一个类。抱歉,如果我误解了您的问题或离这里很远。

【讨论】:

  • 感谢您的快速回复。让我稍微思考一下你说的话,看看会不会奏效。
【解决方案2】:

binder 代理对象有一个 asBinder() 方法,该方法返回底层 IBinder 对象,可用于检查 Binder 代理之间的底层相等性。

我不熟悉该机制,但我看到在 Android 源代码中的 LocationManagerService.java 文件中使用了此方法来注册/取消注册 ILocationListener 对象。

【讨论】:

  • 我已经在我的代码中尝试过这种方法,到目前为止它似乎工作正常。感谢您的回答,将其标记为正确:)
  • > ... 可用于检查 Binder 代理之间的基本相等性。如何? if (binder1 == binder2)?其他?
猜你喜欢
  • 2016-06-27
  • 1970-01-01
  • 2019-11-04
  • 1970-01-01
  • 2023-03-07
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多