【发布时间】: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() 能完成这项工作。感谢您的帮助!