[英]bindService from other app but same userid/process
这是关于基于内存的 IPC(如LocalService示例),但对于在同一进程中运行的两个应用程序:
我有两个应用程序( App1
, App2
)和一个共享项目( Shared
),它为这两个应用程序定义了一些接口和抽象类:
Shared (regular Java project, references android.jar)
- abstract myAbstractService
- Binder myBinder
App1 (Android Project, references Shared)
- MainActivity
App2 (Android Project, references Shared)
- myService extends myAbstractService
两个应用程序在同一进程中运行( my.process
,在<application>
中定义), App2
发布com.www.app2.myService
:
<-- Both Apps run in the same process -->
<manifest <!-- *snip* --> android:sharedUserId="my.shareduser">
<!-- ... -->
<application <!-- *snip* --> android:process="my.process">
<-- App2 exports the service -->
<service android:name="com.www.app2.myService" android:exported="true">
<intent-filter>
<action android:name="com.www.app2.myService" />
</intent-filter>
</service>
这是抽象的myAbstractService
( myService
还没有添加任何新内容):
abstract public class GameClient extends Service
{
private static final String LOGTAG = "GameClient";
private myBinder binder = new myBinder();
public IBinder onBind(Intent intent)
{
Log.d(LOGTAG, "onBind()");
return this.binder;
}
public class myBinder extends Binder
{
public void sendMessage()
{
Log.d(LOGTAG, "sendMessage()");
}
}
}
当我尝试从MainActivity
(App1) 绑定到myService
(App2) 时:
public void onServiceConnected(ComponentName name, IBinder service)
{
Log.d("MS", service.getClass().toString());
main.this.t = (myBinder) service; // Exception in this line of course
}
我得到一个例外:
调试/MS(5464):class com.www.shared.myBinder
错误/AndroidRuntime(5464):java.lang.ClassCastException:com.www.shared.myBinder
由于两个应用程序在同一个进程中运行,内存耦合通信应该可以工作(至少我认为)。 我真的不想使用基于消息或基于广播的通信,因为我会发送相当多的消息。
我怀疑这个异常是由于同一个 class 使用了两个不同的类加载器而发生的? 这种方法根本不可能/错误,还是我错过了什么?
更新:
我的目标是编写一个非常模块化的应用程序,其中 App1 用作其他模块(应用程序)的委托和启动应用程序。 由于我不想将App1
与依赖于它的每个应用程序一起发布,因此我将其作为自己的应用程序。
假设我有第三个应用程序(App3、Android 项目)。 App2 和 App3 都由 App1 启动(负责建立连接,而 App2 和 App3 提供不同的应用程序逻辑(但具有相同的接口)。
再想一想,我认为这也可以通过 android 库来解决(App1 和 Shared 合并为与App2
和App3
启动该库的 Activity 并等待结果的库)? 但是,数据不可打包(网络连接),我不知道如何在 android 市场上独立分发该库(如App2
和App3
在那里发布,但也要求安装该库)。 这会完全解决这个问题吗?
您是对的,您收到此异常是因为涉及两个 class 加载程序。
我添加了接下来的两行代码:
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
...
Log.e(TAG, "Expected class loader: "+myBinder.class.getClass().getClassLoader());
Log.e(TAG, "Class loader: "+service.getClass().getClassLoader());
...
}
并收到这些日志:
Expected class loader: java.lang.BootClassLoader@4001bdb0
Class loader: dalvik.system.PathClassLoader[/data/app/com.inazaruk.shared.service-2.apk]
从日志中可以清楚地看出,使用了另一个 class 加载程序。 这实际上是有道理的,因为您可以在一周后使用不同版本的myBinder
class(或直接或间接通过myBinder
接口传递的任何其他 class)安装App1
应用程序。
更新:
在您的场景中,您应该坚持使用 Android 库。 请注意,Android 库直接嵌入在引用它们的应用程序中。 它们不单独分发。 这是我的帖子,解释了 Android 库与简单的 jars 以及其他相关细微差别的不同之处。
您在 Android 库中仍然具有高度模块化,因为最终的 Android 应用程序仅包含它使用的模块。 但这是编译时模块化,而不是运行时模块化。
Android 库存在一些问题:
AndroidManifest.xml
中所有组件的声明复制到 Android 应用程序的AndroidManifest.xml
中。#1 计划很快修复(根据构建支持路线图)。 #2 和 #3 可能会在 SDK 平台工具的下一版本中得到修复。
不久前我自己尝试过:以前在ClassCastException 中询问了类似的问题,当从另一个 Activity 和 https 绑定到本地服务时, https://stackoverflow.com/questions/3162538/2-apks-running-in-1-process-sharing-code -和-数据。 最终结果几乎相同:共享过程与共享代码不同,因为 class 加载程序层次结构的性质(类似于 J2EE class 加载程序的拆分方式)。
这些类来自不同的 DEX 文件,因此从技术上讲,即使接口相同,这些类也是不同的。 我不相信你想做的事是可能的:我在你的未来看到了 AIDL。
在命名空间“com.www.shared”中是否有一个名为“myBinder”的 class? 因为那是它正在寻找的东西,并且说不存在。 我看到你有 class 但它在什么命名空间中?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.