如何检查两个Android Binder代理对象是否相等?

7
我有一个关于Android Binder的问题。如果我理解正确,Binder可以在进程之间传递。在服务端,有一个Binder对象(原始对象)。在客户端(另一个进程中),有一个处理AIDL数据编组的BinderProxy对象。
我的问题是-如何检查两个BinderProxy对象是否相等?相等指的是它们引用了服务进程中的同一个Binder对象。 我们可以使用equals()方法吗?BinderProxy对象和原始Binder对象具有相同的内存地址吗?
谢谢!
编辑: 针对David Wasser的评论:
我需要这么做的原因有点复杂,但让我看看能否清楚地解释一下--远程服务提供一个AIDL API(客户端通过在onServiceConnected中接收IBinder获得该API)。 AIDL API包含两种方法-- IBinder getInterface(String interfaceName); void releaseInterface(IBinder binder);
其实现代码和其绑定器是动态加载到服务中的,并且未事先知道。服务为客户端应用程序提供这两种AIDL方法,以便根据接口名称访问那些动态加载接口的绑定器。
所以说有App1和App2。每个都会执行“binder1 = getInterface(“SomeInterface1”);”,并获取该动态加载接口'SomeInterface1'的绑定器。使用后,应用程序通过说'releaseInterface(binder1);' 来释放接口绑定器,以便服务可以卸载接口的dex代码并进行一些清理。
但是,除非App1和App2都释放了接口绑定器,否则无法卸载接口dex代码。因此,在服务中,我为每个动态加载的绑定器维护一个引用计数。(例如,一个Map key{Binder}==> value{reference count})。当应用程序执行getInterface()时,我会增加引用计数。当它执行releaseInterface(binder1)时,我应该减少引用计数。但是,要这样做,我需要检查binder1是否等于Map中的绑定器键。
请注意,绑定器已经从服务(原始绑定器对象)传递到客户端应用程序(由getInterface()返回的绑定器代理),然后再次传递回服务(作为releaseInterface()的参数 - 它仍然是代理还是原件?)。
对于相同的接口名称,App1和App2可能会获得不同的绑定器对象(不同的接口实现)。这就是为什么我使用绑定器进行释放的原因。
希望这不太让人困惑!感谢帮助。
Kartik

毫无疑问,BinderProxy对象与原始的Binder对象具有不同的内存地址。由于BinderProxy未覆盖equals()方法,因此我认为您不能将其用于比较。您想要做什么?也许有另一种解决方法。 - David Wasser
谢谢您的快速回复!我已经编辑了我的问题,包括检查两个绑定器是否相等的原因。 - Kartik Sankaran
我已经阅读了您的附加评论。从我的角度来看,我会假设由于您正在服务中进行此比较,所以您将拥有相同的Binder对象,因为代理对象在其他进程中。因此,您应该能够使用equals()。但是,为了确保,为什么不拼凑一个小测试程序,完全按照您所描述的方式进行。这应该很容易做到,并将为您提供明确的答案。我总是更喜欢亲眼看到某些东西,而不是听别人说的话;-) 实证证据是最好的证据! - David Wasser
是的,我认为你关于这点是正确的。让我尝试使用equals()方法。如果它不起作用,我可能会用另一种方式解决这个问题:给每个应用程序一个 cookie 值,并要求在发布绑定器时指定 cookie 值。但是希望 equals() 方法能够解决问题。感谢你的帮助! - Kartik Sankaran
2个回答

11
代理对象有一个 asBinder() 方法,它返回底层的 IBinder 对象,可以用来检查 Binder 代理之间的底层相等性。
我对这个机制不熟悉,但我看到在 Android 源代码中的 LocationManagerService.java 文件中使用了此方法来注册/取消注册 ILocationListener 对象。

我在我的代码中尝试了这种方法,目前看起来它似乎正常工作。感谢您的答案,我将其标记为正确 :) - Kartik Sankaran
可以用来检查 Binder 代理之间的基本相等性。如何实现?使用 if (binder1 == binder2) 吗?还有其他方法吗? - badfd

0
据我所知,这个问题没有简单的解决方案。BinderProxy是android.os.Binder内部的一个final类。你可以在这里找到源代码here。一种解决方法可能是创建一个继承Binder的自定义类,并创建自己的实现来存储Binder实例在BinderProxy中或者反过来。这很困难,因为两个类都没有直接引用另一个类。如果我误解了你的问题或者完全偏离了,请原谅。

谢谢您的快速回复。让我考虑一下您所说的,看看它是否可行。 - Kartik Sankaran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接