(这个答案假定一个本地的“进程中”Service,这无疑是您打算使用的。)
对于您的用例,您实际上使用了多种技术组合来保持Service 运行。
使用“绑定Service 模型”来保留Service,而您的任何Activities 都可见。这很简单;在Activity.onStart() 中调用bindService(),在Activity.onStop() 中调用unbindService()。如果您担心Service 在您的两个Activities 之间的短暂过渡时刻被破坏,请不要担心; Android 足够聪明,可以等待不同应用程序组件的生命周期变化“解决”,然后再决定 Service 未被引用/不需要。
您应该为所有bindService() 调用使用BIND_AUTO_CREATE 标志。请记住,Service 不会在调用 bindService() 时立即创建;这需要几毫秒,并且您必须小心地将控制权返回给框架,方法是从您当前所在的任何生命周期方法(例如,onStart())返回。只有这样,您才会收到对 onServiceConnected() 的调用。
您需要手动跟踪有多少Activities 绑定到您的Service,以确定何时开始您的 2-3 秒清理逻辑。有关有效方法,请参阅this answer。不要担心Service 在您最后一次调用unbindService() 期间被同步销毁——就像bindService() 一样,实际的生命周期状态更改是“延迟的”。
现在的问题是,此时如何让Service 在这额外的 2-3 秒内保持活动状态(您确定打开的Activities 的数量已降至 0)?好吧,您可以直接致电startService()。您甚至可以从 Service 子类中的方法调用它;只要您有一个有效的Context 可用,这并不重要。 startService() 向系统表明您希望保留Service,无论有多少Activities(或其他客户端)可能绑定到它。在这种情况下,Service 不会重新启动——它已经在运行了!
清理完成后,您可以致电stopService(),或者更好的是stopSelf()。这有效地取消了startService() 调用,并告诉操作系统,“我完成了”。预计不久后将致电Service.onDestroy()。
请记住,您的Activities 之一可能会异步弹出,并在清理完成之前重新绑定到Service。这是一种边缘情况,但很容易处理。 Service 只有在以下两个条件都为真时才会被销毁:1.) 没有绑定/绑定客户端,以及 2.) 不存在对 startService() 的未取消调用。
请注意,在 Oreo 及更高版本上,系统可能会非常积极地杀死具有背景 Services 的应用程序。根据this doc 的说法,与用户交互会将您列入白名单“几分钟”,所以我认为 2-3 秒就可以了。同样,如果您正在处理“高优先级 FCM 消息”(我假设您的意思是“推送”消息),您将被列入白名单,并允许再过几分钟执行 @ 987654364@(这次使用startService()/stopSelf() 方法)。