Android - 服务是不是在进程之间共享?

Posted

技术标签:

【中文标题】Android - 服务是不是在进程之间共享?【英文标题】:Android - Are services shared among processes?Android - 服务是否在进程之间共享? 【发布时间】:2010-12-13 15:11:28 【问题描述】:

我有一个 android 库,它作为 jar 文件分发,用于包含在 3rd 方应用程序中。

jar 文件中有一个 Android 服务。 该服务通过 jar 文件中的外观类公开。 因此,第 3 方不直接绑定到服务,他们只是使用外观类。

我对这个架构有 2 个问题:

1) 如果两个完全独立的第 3 方应用程序使用此外观(不同的包名称、不同的用户 ID 等)类是创建的服务的两个实例还是共享一个实例?

2) 如果服务直接绑定到第 3 方应用程序而不是通过外观访问,这会有所不同吗?

附: http://developer.android.com/reference/android/app/Service.html 不回答这些问题。

【问题讨论】:

【参考方案1】:

答案是一次只会运行一个服务实例(无论如何,除非你跳过一些疯狂的圈子让它运行多次)。多次调用 Context.startService() 和 onCreate() 不会创建它的其他实例。如果您需要在第 3 方连接时执行任何操作,则应通过 onStartCommand 或从 Context.bindService() 返回的 Binder 对象传递。

您的模型独立于 Android 中的底层服务处理,无论您的外观正在访问服务还是 2+ 3 方正在访问服务,行为都是相同的。

【讨论】:

我知道在单个应用程序中使用服务时肯定是这种情况,但是我仍然怀疑这是否适用于访问重新打包的 jar 文件中提供的服务的多个应用程序在每个 APK 中。如果使用多个不同版本的 jar 会怎样? 根据我的经验,如果有,它将使用当前正在运行的服务,如果没有,它将启动包含在 dex 中的服务。我真的希望 apk 有这种情况的依赖信息。【参考方案2】:

好的,我对此进行了快速测试。

我修改了提供的 jar 文件以将 onBind Intent 中传递的值存储到 2 个静态变量中。 (stAppID 和 stAppVer) 并在服务上调用某个方法时打印出来

当绑定到服务时,每个应用都会通过 Intent 传入不同的值。

如果服务确实在应用程序之间共享,我希望有两件事:

    静态时进程 ID 相同 被打印。 两个应用程序都安装后 绑定到随后的服务 调用打印的方法 静态变量应该打印出来 相同的值。

这是我的测试的日志输出。


E/************ ServiceTest *************(  744): ***************************************************
E/************ ServiceTest *************(  744): ***************************************************
E/************ ServiceTest *************(  744): Thread = main
E/************ ServiceTest *************(  744): stAppID = APP AAAAAAAAAAAAA
E/************ ServiceTest *************(  744): stAppVer = VER AAAAAAAAAAAAA
E/************ ServiceTest *************(  744): ***************************************************
E/************ ServiceTest *************(  744): ***************************************************
D/dalvikvm(  744): GC freed 4963 objects / 267800 bytes in 100ms
D/dalvikvm(  778): GC freed 2640 objects / 151400 bytes in 105ms
I/ActivityManager(  578): Starting activity: Intent  flags=0x10100000 comp=com.a.service.test/com.a.service.test.TrackingSample 
W/InputManagerService(  578): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@4370dac0
I/ActivityManager(  578): Starting activity: Intent  flags=0x10100000 comp=com.b.service.test/com.b.service.test.TrackingSample 
W/InputManagerService(  578): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@436f7760
D/MMT     (  778): Creating new last event timestamp record for UIApplicationWillTerminateNotification
D/MMT     (  778): Run closed
D/MMT     (  778): Run started
E/************ ServiceTest *************(  778): ***************************************************
E/************ ServiceTest *************(  778): ***************************************************
E/************ ServiceTest *************(  778): Thread = main
E/************ ServiceTest *************(  778): stAppID = APP BBBBBBBBBBBBBBB
E/************ ServiceTest *************(  778): stAppVer = VER BBBBBBBBBBBBBBB
E/************ ServiceTest *************(  778): ***************************************************
E/************ ServiceTest *************(  778): ***************************************************
E/************ ServiceTest *************(  744): ***************************************************
E/************ ServiceTest *************(  744): ***************************************************
E/************ ServiceTest *************(  744): Thread = main
E/************ ServiceTest *************(  744): stAppID = APP AAAAAAAAAAAAA
E/************ ServiceTest *************(  744): stAppVer = VER AAAAAAAAAAAAA
E/************ ServiceTest *************(  744): ***************************************************
E/************ ServiceTest *************(  744): ***************************************************
D/dalvikvm(  744): GC freed 836 objects / 131136 bytes in 86ms

由此可见。所需条件均不成立,因此 我得出结论,该服务未在应用程序之间共享。 (进程 ID 是每个日志行中冒号前括号中的数字)

仔细想想,这是有道理的。 操作系统如何确定重新打包的 jar 包含相同版本的服务。 Android 服务上没有声明版本元数据。

另一个问题是该服务使用数据库。如果该数据库在应用程序之间共享,则会存在安全风险。

【讨论】:

以上是关于Android - 服务是不是在进程之间共享?的主要内容,如果未能解决你的问题,请参考以下文章

Android中的IPC进程通信方式第一篇

Android图形系统(八)-app与SurfaceFlinger共享UI元数据过程

Android探索之AIDL实现进程间通信

Linux:是不是可以在进程之间共享代码?

Android跨进程通信-共享内存

在 C 语言中使用 POSIX 在多个进程(不是线程,仅进程)之间共享二进制信号量