2011-06-01 188 views
7

首先我想说两件事。首先是,如果这个问题已经被问到,我很抱歉,我已经搜索了围绕这个主题的类似问题,但无法找到解决方案。其次,对于冗长的问题抱歉,请让我知道任何错误,我一定会做出适当的修改:)。Android共享服务?

我对Android开发相对较新(约2个月),所以请原谅我的无知。我的问题是关于android服务。

我的问题是如下,我创建了以下三个应用领域:

  • 其中包含一个小的测试服务(为myService)一个Android库。
  • 有权访问android库的应用程序(TestApplicationOne)。
  • 另一个应用程序(TestApplicationTwo)也可以访问android库。

我目前的解决方案的工作原理如下,TestApplicationOne引用自定义库,并使用该库连接到通过bindService()方法服务(为myService)。连接成功后,应用程序将自己添加到位于myService内的观察员集合中。每次服务需要广播消息时,都会通知此集合中的每个对象。

运行时,上述解决方案似乎工作正常。但是,我现在有另一个应用程序(TestApplicationTwo),它也想使用与上面相同的服务。 TestApplicationTwo的实现是针对第一个应用程序的相同工作原理/规范(TestApplicationOne)创建的。

我遇到的问题是,当服务在任一应用程序中启动时,其他应用程序不会收到任何事件通知。

我试图实现几种方法来解决这个问题。比如使用Singleton模式来保留单个实例,但问题似乎仍然存在。我对此的唯一理解是,每次启动应用程序时,都会创建一个新的库实例。因此,TestApplicationOne中引用的库与TestApplicationTwo中引用的库不同,并且因此未被通知。

有没有人在这个问题上有任何经验?或者可以想出任何可能的解决方案?

非常感谢您提前给予任何帮助。

约翰

回答

10

我的问题是,当服务或者应用程序已启动,其他应用程序不会得到通知的任何事件。

那是因为你有两个服务。仅仅因为服务被打包在Android库项目中并不奇怪地导致两个不同的应用程序使用相同的副本。

如使用Singleton模式保留单个实例,但问题似乎仍然存在。

这两个应用程序都在独立的进程中运行,并有它们自己的私有服务副本。

我唯一的理解就是每次启动任何一个应用程序时,都会创建一个库的新实例。

库没有实例。 Android库项目不是DLL--它们更类似于静态库。

因此,TestApplicationOne中引用的库与TestApplicationTwo中引用的库不是同一实例,因此不会被通知。

更准确地说,TestApplicationOne中的服务是TestApplicationTwo副本中服务的单独副本。

或者可以想出任何可能的解决方案?

没有两个单独的应用程序。

或者,重新设计您的应用程序,使其中只有一个拥有该服务,另一个使用第一个应用程序提供的服务。

或者,在两个应用的清单中禁用该服务,并使用稳定的<intent-filter>(例如,使用自定义操作字符串)导出该服务。要安装/运行的第一个应用程序使用PackageManager来查看服务是否存在(例如,它不是真正的第一个应用程序) - 如果看到该服务不存在,它将启用它自己的该服务的副本。然后,第二个应用程序通过相同的过程,看到该服务已经存在,并使用远程副本而不是启用它自己的。

第二个或第三个都不是很容易,仅仅是因为数据只存在于一个应用程序(具有服务的应用程序)中。因此,如果该应用程序被卸载,则另一个应用程序将被锁定,即使它恰好有可用的服务代码作为禁用的组件。如果应用程序清楚地向用户描述为具有主要/次要关系(例如,应用程序及其插件),那么这可能会生效 - 如果应用程序不在那里,用户希望不会期望插件工作,例如。当然,在这种情况下,插件首先不会拥有自己的服务副本,但总是会看到主应用程序。

+0

钝,但答案都是一样的。感谢您的帮助。成品只会由我个人使用,所以带有意向过滤器的导出解决方案看起来是一种可行的方法。我会进一步研究这个建议,并用我选择的方法更新这个问题。再次感谢您的帮助。 – JohnHodkinson 2011-06-01 17:07:28

+0

我很惊讶你不提及分享一个过程。也许答案已过时? – dcow 2014-09-17 06:21:16

+0

@dcow:最好的情况是,如果生产场景表示这两个应用程序由相同的签名密钥签名,那么这就行得通了,而且这个问题还不清楚。其次,我真诚地希望你描述的场景仍然涉及单独的虚拟机(只是在一个进程中),在这种情况下,它不会有帮助。两个应用程序在同一个进程中共享同一个虚拟机将会产生问题,因为如果没有其他的类路径冲突。 – CommonsWare 2014-09-17 10:38:16

2

我不确定,但我认为android:singleUser="true"服务标签的属性可能是你正在寻找的。

If set to true, a single instance of this component will run 
for all users. [boolean] 

如果这并不帮助,那么你可以考虑在你的服务在你的2个应用程序而不是访问服务作为一个对象发送广播消息,为每个活动,并有BroadcastRecievers一个解决方案...