在最近的版本中,Android似乎在后台引入了对运行服务的多重限制,这对我们设备的电池寿命来说当然是个好消息。我的目标是创建一个应用程序来坚持这一点,只运行一个服务,只要用户与应用程序交互(这似乎是他们的目标)。但我一点也不清楚你是如何正确地实现这一点的。我的要求如下:
在我看来,绑定服务似乎是要使用的。但我不清楚我的需求将如何与绑定服务模型相匹配。有没有人在这方面有经验,谁能给我指明正确的方向?
编辑:在这种情况下,“服务”是一个本地的、进程中的服务,它不打算被外部访问。
发布于 2019-01-23 19:13:10
(这个答案假定是一个本地的“进程中”Service,这无疑是您打算使用的。)
对于用例,您实际上使用了多种技术来保持Service运行。
使用“绑定Service模型”将Service保持在可见的任何一个Activities中。这很简单:在Activity.onStart()中调用Activity.onStart(),在Activity.onStop()中调用unbindService()。如果您担心Service在两个Activities之间的短暂转换中被破坏,不要担心;Android非常聪明,可以等待不同应用程序组件的生命周期变化“解决”,然后才决定Service是不引用/不需要的。
您应该在所有的BIND_AUTO_CREATE调用中使用bindService()标志。请记住,Service不是在调用bindService()时立即创建的;它需要几毫秒时间,您必须小心地从当前所在的任何生命周期方法(例如onStart())返回对框架的控制。只有到那时你才能接到onServiceConnected()的电话。
您需要手动跟踪有多少Activities绑定到您的Service,以便确定何时开始2-3秒的清理逻辑。有关有效方法,请参见这个答案。不要担心Service在上一次unbindService()调用期间被同步销毁--就像对bindService()一样,实际的生命周期状态更改是“延迟的”。
现在的问题是,在这一点上,如何使Service保持额外的2-3秒(确定打开Activities的数量已经降到0)?那么,您可以简单地调用startService()。您甚至可以从Service子类中的方法调用它;只要您有一个有效的可用Context,这并不重要。无论有多少startService() (或其他客户端)可能绑定到系统,Service都会指示您希望将Service保持在系统中。在这种情况下,Service将不会重新启动--它已经在运行了!
一旦清理完成,您就可以调用stopService(),或者更好的是调用stopSelf()。这实际上取消了startService()调用,并告诉操作系统“我完成了”。期望在不久之后给Service.onDestroy()打个电话。
请记住,在清理完成之前,您的一个Activities可能会异步弹出,并重新绑定到Service。这是一个边缘的情况,但一个很容易处理。只有当这两种条件都为真时,Service才会被销毁:1)。没有任何客户端绑定/绑定,和2)。不存在未取消的对startService()的电话.
请注意,在奥利奥和以后,该系统可以相当积极地杀死应用程序的背景Services。根据这位医生的说法,与用户交互会让你在白名单上“几分钟”,所以我想2-3秒就可以了。类似地,如果您正在处理“高优先级FCM消息”(我假设这就是您所说的“推送”消息),您将被放在白名单上,并允许再在几分钟内执行Service (这次使用startService()/stopSelf()方法)。
https://stackoverflow.com/questions/54323680
复制相似问题