Android会杀死每个服务还是整个过程?

我们中的很多人都知道(如果没有调用Service.startForeground() ,Android中的Service将被系统杀死。 但是,这是整个故事…?


我正在处理一些遗留代码,将“系统”权限应用移植到Play商店。 这个应用程序有5个后台服务(不调用startForeground() ),直到现在,由于应用程序运行的“系统”权限,它是安全的。 它被安装在一个自定义的设备上。 由于时间紧迫和预算紧张,将这5个重构为1并不是一个短期解决scheme,但我们希望尽快开始公测。

简短的问题是:

  • 如果没有前台的ActivityService ,Android会杀死每个单独的后台服务,还是只是杀死进程

这里有一些关于进程和线程的Android文档的信息 ,讨论Android在压力下如何终止进程:

Android可能决定在某个时候closures某个进程 ,当内存不足时,其他进程会立即为用户提供服务。 在被杀死的进程中运行的应用程序组件因此被销毁。 当这些组件再次为他们工作时,将再次启动一个进程。

在决定要杀死哪些进程时,Android系统会权衡他们对用户的相对重要性。 例如,与容纳可见活动的进程相比,它更容易closures在屏幕上不再可见的进程托pipe活动。 因此,是否终止进程的决定取决于在该进程中运行的组件的状态。


常识说“ Android会杀了服务

个人经验表明, Android也会杀死进程本身(如上面的报价中所述)。 这可以通过在Application对象中存储对象来显示,并且注意到在服务被终止后它们被重新初始化。


考虑到上述情况, 解决这个问题有几个select

1)做正确的事情

将5个服务重构为1,运行在不同的线程上。 把1服务放在前台。 问题解决了。

不幸的是,目前没有这方面的预算,而且我们希望根据项目时间表find一个快速解决scheme。

这是最后的解决scheme,将会实施到全面生产。

2)许多通知

在前台启动每个服务,每个都有自己的Notification图标。

这是一个混乱的解决scheme,但将用于testing现场试验,给我们一些时间。

我认为这是“蛮力”的方法。

3)由一个服务保护的进程

如果是被杀死的进程,而不是每个单独的服务,那么运行一个前台服务就足够了。

这会“阻止”(即降低)Android杀死进程的可能性。

所有5个服务将因此生存。

4)一个服务统治他们

服务文档告诉我们,如果服务绑定到另一个上下文,那么

stopService()或stopSelf()实际上并不停止服务,直到所有客户端解除绑定。

如果我从一个单一的前台服务绑定到其他服务,它们会保持活着吗?


所以:

  • Android会杀死每个未绑定的后台服务吗?
  • 或者它只是杀死应用程序正在运行的虚拟机?

更新

经过18个 41小时的testing#3( 过程受到一个服务的保护 ),所有6个服务仍在运行(5个旧加上1个新的)。

因此,如果没有前台活动或服务正在运行,Android看起来会杀死进程

Solutions Collecting From Web of "Android会杀死每个服务还是整个过程?"

如果没有前台的Activity或Service,Android会杀死每个单独的后台服务,还是只是杀死进程?

Android不会杀死个人的ActivitiesServices ,这没有多大意义。 例如,如果一个Activity在后台,Android将永远不会决定专门杀死这一个Activity 。 无论内存中的Java Object是什么types,所有这些Object实例共享相同的命运:如果不再需要/使用它们将被垃圾收集。 人们经常谈到一个Activity在后台被杀害,这真的是误导,因为他们只是意味着它可以被垃圾收集,最终将是垃圾。 所以这个垃圾收集是摧毁一个对象的特定实例的东西。 它与低内存的设备无关。

当Android内存不足时,它会决定杀死一个完整的进程,而且你已经阅读过文档中select的最不重要的文件。

我想告诉你的是,这是两个根本不同的过程。 一个是Android操作系统在内存不足时杀死不重要的进程,另一个是不断寻找不再使用的内存的垃圾回收器。

常识说“Android会杀了服务”

正如我上面所解释的那样,这可能是误导性的,并不完全正确,如果设备内存不足,将会终止整个过程,而不仅仅是特定的Service 。 这与不再使用垃圾收集Service不同。


现在解决您的问题:

将5个服务重构为1,运行在不同的线程上。 把1服务放在前台。 问题解决了。

这显然是最好的select,但正如你所说,你现在不能实现这一点。

在前台启动每个服务,每个都有自己的通知图标。

这将是一种不好的解决scheme,没有理由有多个通知。 其他选项显然更好。

如果是被杀死的进程,而不是每个单独的服务,那么运行一个前台服务就足够了。

这绝对可以工作,我会尝试。

服务文档告诉我们,如果服务绑定到另一个上下文,那么

stopService()或stopSelf()实际上并不停止服务,直到所有客户端解除绑定。

如果我从一个单一的前台服务绑定到其他服务,它们会保持活着吗?

在我看来,这是下一个最好的select。


我最初考虑在自己的过程中启动每个Service 。 但我不确定这是否适用于您。 特别是如果你想保持所有 Services在任何时候运行。 在自己的过程中启动Service的好处显然是独立于应用程序的其余部分。 所以即使某些部分因内存限制而死亡,其余的应用程序仍然会在其他进程中运行。

你有没有想过使用inheritance来解决这个问题? 这可能是最简单的方法来实现你的select1)

每个android应用程序都是zygote进程的一个分支,并有自己的进程。 每个应用程序进程可以承载更多的活动和服务:因此,可以明确地说,杀死一个进程(例如:kill PID)会杀死里面的所有东西。

默认情况下,服务与其应用程序处于同一个进程中; 但是可以让服务在专门的单独stream程上运行,并在清单中声明:

 <service android:name=".MyService" android:isolatedProcess=true />