安卓共享服务?

9
首先,我要说两件事。第一,如果这个问题已经有人问过,请原谅我。我在这个话题周围搜索了类似的问题,但没能找到解决办法。其次,对于这个问题的详细描述,我很抱歉。如果有错误,请让我知道,我会进行适当的更改:)。
我相对较新于Android开发(大约2个月),所以请原谅我的无知。我提出的问题与Android服务有关。
我的问题如下,我创建了以下3个应用程序:
1. 包含一个小测试服务(myService)的Android库。 2. 具有访问Android库权限的应用程序(TestApplicationOne)。 3. 另一个也具有访问Android库权限的应用程序(TestApplicationTwo)。
我的当前解决方案如下,TestApplicationOne引用自定义库并使用此库通过bindService()方法连接到服务(myService)。连接成功后,该应用程序将自身添加到myService中的观察者集合中。该集合中的每个对象在服务需要广播消息时都会收到通知。
运行上述解决方案时,似乎工作得很好。但是,我现在有另一个应用程序(TestApplicationTwo)也想使用与上面相同的服务。 TestApplicationTwo的实现与第一个应用程序(TestApplicationOne)的实现方式相同。
我的问题是,当在任何一个应用程序中启动服务时,其他应用程序都不会收到任何事件通知。
我尝试了几种方法来解决这个问题。例如使用Singleton模式保留单个实例,但问题似乎仍然存在。我的唯一理解是,每次启动任何一个应用程序时,都会创建库的新实例。因此,在TestApplicationOne中引用的库与在TestApplicationTwo中引用的库不是同一个实例,因此无法获得通知。
有人有关于这个问题的任何经验吗?或者可以想到任何可能的解决方案吗?
提前感谢您的帮助,非常感谢。
约翰
2个回答

10
我遇到的问题是,当服务在任何一个应用程序中启动时,另一个应用程序不会收到任何事件通知。 这是因为你有两个服务。仅仅因为服务打包在Android库项目中,并不会以某种神奇的方式使两个不同的应用程序使用相同的副本。 例如,使用单例模式来保留单个实例,但问题似乎仍然存在。 两个应用程序在单独的进程中运行,并且拥有自己的私有服务副本。 我唯一理解的是,每次启动任何一个应用程序时,都会创建库的新实例。 库没有实例。Android库项目不是DLL库——它们更类似于静态库。 因此,TestApplicationOne中引用的库与TestApplicationTwo中引用的库不是同一实例,结果无法收到通知。 或者想出其他可能的解决方案吗? 不要有两个单独的应用程序。 或者重新设计您的应用程序,使只有一个应用程序具有服务,而另一个应用程序使用第一个应用程序中的服务。 或者,在两个应用程序的清单中禁用服务,使用稳定的导出(例如,使用自定义操作字符串)。安装/运行的第一个应用程序使用PackageManager查看服务是否存在(例如,它不是真正的第一个应用程序)-看到服务不存在,它将启用自己的服务副本。然后,第二个应用程序经过同样的过程,看到服务已经存在,使用远程副本而不是启用自己的服务。

第二种和第三种都不太容易,因为数据只存在于一个应用程序中(具有服务的应用程序)。因此,如果该应用程序被卸载,则另一个应用程序将无法使用,即使它恰好有已禁用的组件作为服务代码。如果向用户清楚地描述这些应用程序之间存在主/次关系(例如,应用程序及其插件),那么可能会起作用--用户希望插件在没有应用程序的情况下能正常工作,例如。当然,在这种情况下,插件本身就没有服务的副本,而是始终寻找主应用程序。


虽然直接,但仍是一个答案。感谢您的帮助。最终产品只会被我个人使用,因此使用intent-filter导出解决方案似乎是一个可行的方法。我将进一步研究这个建议,并更新这个问题以反映我的选择方法。再次感谢您的帮助。 - user456236
我很惊讶你没有提到共享进程。也许这个答案已经过时了? - dcow
@dcow:最好的情况是,如果生产场景要求两个应用程序由相同的签名密钥签名,那么这种方法才能起作用,但从问题描述中并不清楚。其次,我真诚地希望您所描述的场景仍然涉及单独的虚拟机(只是恰好在一个进程中),在这种情况下它将没有帮助。如果两个应用程序共享同一进程中的同一虚拟机,则可能会出现类路径冲突等问题。 - CommonsWare
1
@CommonsWare 不是的,我在谈论在共享进程中运行服务,并通过标准服务API与两个不同应用程序的同一实例进行通信。 - dcow

2
我不太确定,但我认为 android:singleUser="true"服务标记的属性可能是你要找的。
If set to true, a single instance of this component will run 
 for all users. [boolean]

如果这不起作用,那么你可以考虑一种解决方案,即为每个事件从服务发送广播,并在你的两个应用程序中使用BroadcastRecievers代替访问服务对象...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接