绑定来自不同 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 的服务的主要内容,如果未能解决你的问题,请参考以下文章

我可以绑定来自不同虚拟主机的队列吗?

多个APK版本具有不同的功能

绑定来自两个不同 qml 文件的两个元素

如何从不同的 .apk 连接到远程服务

绑定来自不同xaml的数据(矢量绘图)

将来自不同文件夹的多个 csv 文件(相似名称)合并到一个 csv 中并逐行绑定它们 [关闭]