绑定来自不同APK的服务

时间:2013-02-26 10:50:58

标签: android android-service classcastexception android-binder

我需要一些帮助来通过花费Binder类绑定服务。

我有2个APK。第一个声明了一个服务,我想从第二个APK的活动中绑定它。

两个APK都使用相同的sharedUserId和相同的android:process。

由于它们在同一个进程中运行,我不想使用AIDL进行IPC通信(我已经尝试过了,但是我不想使用它,因为我只使用了一个进程)。

我可以启动/绑定服务,但我无法获得对服务的引用:

LocalBinder binder = (LocalBinder);
mService = binder.getService();

我得到例外:

E/AndroidRuntime(6145): java.lang.ClassCastException: 

是否可以通过在我的案例中扩展IBinder类来绑定服务?

由于

2 个答案:

答案 0 :(得分:1)

我从未尝试过这个,但我怀疑每个.apk都是使用自己的ClassLoader加载的。这意味着Dalvik VM会将每个.apk中具有相同名称的两个相同的类视为完全不同的类。

我相信你会发现这是不可能解决的。

因此,您应该使用aidl。我想你有两个反对的意见。

  • 您可能不想花时间将所有数据编组到Parcelable类等等。但是,如上所述,我不相信您可能会找到直接传递数据的方法两个.apks之间的Java对象,即使在相同的进程中运行,所以你别无选择。
  • 也许你担心表现。但是你不必担心,因为Binder调用(包括aidl调用)在它们处于同一个进程时变成普通的函数调用。

答案 1 :(得分:0)

使用Messenger:这是执行进程间通信(IPC)的最简单方法,因为Messenger将所有请求排队到一个线程中,这样您就不必将服务设计为线程-safe。

如果您需要您的界面跨不同的进程(意味着不同的APK),您可以使用Messenger为服务创建一个界面。通过这种方式,服务定义了一个响应不同类型的Message对象的Handler。此Handler是Messenger的基础,然后可以与客户端共享IBinder,允许客户端使用Message对象向服务发送命令。此外,客户端可以定义自己的Messenger,因此服务可以发回消息。

如果您需要服务与远程进程通信,则可以使用Messenger为您的服务提供界面。此技术允许您执行进程间通信(IPC),而无需使用AIDL。

以下是如何使用Messenger的摘要:

该服务实现一个Handler,它接收来自客户端的每个调用的回调。     该服务使用Handler创建Messenger对象(它是对Handler的引用)。     Messenger创建一个IBinder,服务从onBind()返回到客户端。     客户端使用IBinder实例化Messenger(引用服务的Handler),客户端使用它将Message对象发送到服务。     该服务在其Handler中接收每个Message,特别是在handleMessage()方法中。

通过这种方式,客户端无法调用服务。相反,客户端传递服务在其处理程序中接收的消息(消息对象)。