绑定来自不同 APK 的服务
Posted
技术标签:
【中文标题】绑定来自不同 APK 的服务【英文标题】:Binding a service from a different APK 【发布时间】:2013-02-26 10:50:57 【问题描述】:我需要一些帮助来通过扩展 Binder 类来绑定服务。
我有 2 个 APK。第一个声明了一个服务,我想从第二个 APK 的活动中绑定它。
两个 APK 使用相同的 sharedUserId 和相同的 android:process。
由于它们在同一个进程中运行,我不想使用 AIDL 进行 IPC 通信(我已经尝试过,它正在工作,但考虑到我只使用一个进程,我不想使用它)。
我可以启动/绑定服务,但我无法获得对服务的引用:
LocalBinder binder = (LocalBinder);
mService = binder.getService();
我得到了例外:
E/AndroidRuntime(6145): java.lang.ClassCastException:
在我的情况下,是否可以通过扩展 IBinder 类来绑定服务?
谢谢
【问题讨论】:
【参考方案1】:我从未尝试过,但我怀疑每个 .apk 都使用自己的 ClassLoader
加载。这意味着来自每个 .apk 的两个具有相同名称的相同类将被 Dalvik VM 视为完全不同的类。
我相信你会发现这是不可能解决的。
因此,您应该使用aidl。我想你对aidl有两个反对意见。
您可能不想花时间将所有数据编组到Parcelable
类等中。但是,如上所述,我认为您不太可能找到将数据直接作为 Java 对象传递的方法两个 .apk 之间,即使在同一个进程中运行,所以你别无选择。
也许您担心性能问题。但您不必担心,因为 Binder 调用(包括aidl 调用)在同一个进程中时只是普通的函数调用。
【讨论】:
【参考方案2】:使用 Messenger:这是执行进程间通信 (IPC) 的最简单方法,因为 Messenger 将所有请求排队到单个线程中,因此您不必将服务设计为线程-安全。
如果您需要您的界面跨不同的进程(意味着不同的 APK)工作,您可以使用 Messenger 为服务创建一个界面。通过这种方式,服务定义了一个 Handler 来响应不同类型的 Message 对象。这个 Handler 是 Messenger 的基础,它可以与客户端共享一个 IBinder,允许客户端使用 Message 对象向服务发送命令。此外,客户端可以定义自己的 Messenger,因此服务可以发回消息。
如果您需要您的服务与远程进程进行通信,那么您可以使用 Messenger 为您的服务提供接口。此技术允许您执行进程间通信 (IPC),而无需使用 AIDL。
以下是如何使用 Messenger 的摘要:
该服务实现了一个处理程序,该处理程序接收来自客户端的每个调用的回调。 该服务使用 Handler 创建一个 Messenger 对象(它是对 Handler 的引用)。 Messenger 创建一个 IBinder,服务从 onBind() 返回给客户端。 客户端使用 IBinder 来实例化 Messenger(它引用服务的处理程序),客户端使用它来向服务发送消息对象。 服务在它的 Handler 中接收每条消息——特别是在 handleMessage() 方法中。
这样,客户端就没有调用服务的方法了。相反,客户端传递服务在其处理程序中接收到的消息(消息对象)。
【讨论】:
以上是关于绑定来自不同 APK 的服务的主要内容,如果未能解决你的问题,请参考以下文章