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

时间:2014-07-22 09:33:26

标签: android service process

我们中的许多人都知道(如果松散的话)Android中的Service如果不调用Service.startForeground()就会被系统杀死。但这是整个故事......?


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

简短的问题是:

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

以下是来自Processes and Threads的Android文档的一些信息,讨论了Android在压力下如何终止进程:

  

当内存时,Android可能决定关闭某个进程   很低,并且需要更直接的其他流程   为用户服务。在流程中运行的应用程序组件   因此被杀害了。再次启动进程   那些组件,当他们再次为他们工作时。

     

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


常识知道" Android会杀死服务"

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


考虑到上述情况,有一些解决问题的方法

1)做正确的事

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

不幸的是,目前没有预算,我们宁愿根据项目时间表找到快速解决方案。

这是将要实施的最终解决方案,以便全面投入生产。

2)许多通知

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

这是一个混乱的解决方案,但适用于beta现场试验,为我们买了一些时间。

我认为这是"蛮力"做法。

3)受一项服务保护的流程

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

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

所有5项服务都将继续存在。

4)一项服务来统治他们

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

  

stopService()或stopSelf()实际上不会停止服务,直到   所有客户解开。

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


所以:

  • Android会杀死每个未绑定的后台服务吗?
  • 或者只是杀死运行该应用程序的VM?

更新

18 41小时测试#3(受一个服务保护的进程)后,所有6个服务仍在运行(5个旧加1个新服务)。

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

2 个答案:

答案 0 :(得分:6)

  

如果没有前台活动或服务,Android会杀死每个   个人后台服务,还是只是杀了这个过程   本身?

Android不会杀死个人ActivitiesServices,这不会有多大意义。例如,如果Activity处于后台,则Android永远不会决定专门杀死此Activity。所有那些Object实例共享相同的命运并不重要。Object实例共享相同的命运:如果不再需要/使用它们,它们将被垃圾收集。人们经常谈论Activity在背景中被杀,这真的是误导,因为他们只是意味着它可以被垃圾收集,最终会被收集。因此,这种垃圾收集会破坏对象的特定实例。它与内存不足的设备无关。

当Android内存不足时,它将决定终止整个过程,正如您在文档中已经阅读过的那样,它会选择最不重要的过程。

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

  

众所周知," Android会杀死服务"

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


现在问你的解决方案:

  

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

这显然是最好的选择,但正如你所说,你现在无法实现这一点。

  

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

这将是一种糟糕的解决方案,没有理由拥有多个通知。其他选择显然更好。

  

如果是被杀的过程,而不是每个人   服务,那么拥有一个前景就足够了   服务运行。

这肯定有用,我会试试。

  

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

     

stopService()或stopSelf()实际上不会停止服务,直到   所有客户解开。

     

如果我从单个前台服务绑定到其他服务,将会   让他们都活着?

在我看来,这是下一个最佳选择。


我最初考虑过在自己的进程中启动每个Service。但我不确定这是否适用于您。特别是如果你想让所有 Services一直在运行。在其自己的过程中启动Service的好处显然是它独立于应用程序的其余部分。因此,即使某些部分由于内存限制而被杀死,应用程序的其余部分也将继续在另一个进程中运行。

你有没有想过使用继承来解决问题?这可能是实施您的选项 1)的最简单方法。

答案 1 :(得分:1)

每个Android应用程序都是一个zygote进程的分支,并有自己的进程。每个应用程序进程都可以托管更多的活动和服务:因此,定义,杀死一个进程(例如:kill PID)将杀死内部的所有内容。

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

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