我们中的许多人都知道(如果松散的话)Android中的Service
如果不调用Service.startForeground()
就会被系统杀死。但这是整个故事......?
我正在研究一些遗留代码,移植"系统" Play商店的权限应用。由于"系统"该应用程序有5个后台服务(不调用startForeground()
),直到现在,它们都是安全的。该应用运行的权限。它安装在自定义设备上。由于时间紧迫和预算紧张,将这5个重构为1不是短期解决方案,但我们希望尽快转向公测。
简短的问题是:
Activity
或Service
,Android是否会杀死每个单独的后台服务,还是只会杀死进程本身?以下是来自Processes and Threads的Android文档的一些信息,讨论了Android在压力下如何终止进程:
当内存时,Android可能决定关闭某个进程 很低,并且需要更直接的其他流程 为用户服务。在流程中运行的应用程序组件 因此被杀害了。再次启动进程 那些组件,当他们再次为他们工作时。
在决定杀死哪些进程时,Android系统会对其进行权衡 对用户的相对重要性。例如,它更容易关闭 下载不再可见的活动的进程 屏幕,与托管可见活动的进程相比。 决定 因此,是否终止进程取决于状态 在该过程中运行的组件。 ...
常识知道" Android会杀死服务"
个人经验表明, Android也会杀死进程本身(如上面引用中所述)。这可以通过在Application
对象中存储对象来显示,并注意在服务被终止后它们会被重新初始化。
考虑到上述情况,有一些解决问题的方法:
将5个服务重构为1,在各种不同的线程上运行。将1服务带到前台。问题解决了。
不幸的是,目前没有预算,我们宁愿根据项目时间表找到快速解决方案。
这是将要实施的最终解决方案,以便全面投入生产。
在前台启动每项服务,每项服务都有自己的Notification
图标。
这是一个混乱的解决方案,但适用于beta现场试验,为我们买了一些时间。
我认为这是"蛮力"做法。
如果它是被杀死的进程,而不是每个单独的服务,那么运行单个前台服务就足够了。
这会阻止" (即降低Android)杀死进程的可能性。
所有5项服务都将继续存在。
docs on Services告诉我们,如果服务绑定到另一个上下文,那么
stopService()或stopSelf()实际上不会停止服务,直到 所有客户解开。
如果我从单个前台服务绑定到其他服务,那么它们会保持活着吗?
18 41小时测试#3(受一个服务保护的进程)后,所有6个服务仍在运行(5个旧加1个新服务)。
如果没有前台活动或服务正在运行,那么看起来好像Android会杀死进程。
答案 0 :(得分:6)
如果没有前台活动或服务,Android会杀死每个 个人后台服务,还是只是杀了这个过程 本身?
Android不会杀死个人Activities
或Services
,这不会有多大意义。例如,如果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 />