【问题标题】:Android - How to decide whether to run a Service in a separate Process?Android - 如何决定是否在单独的进程中运行服务?
【发布时间】:2011-06-07 05:00:14
【问题描述】:

我正在开发一个在多个小时内收集传感器数据的 Android 应用程序。 为此,我们有一个服务来收集传感器数据(例如加速度、GPS 等),进行一些处理并将它们远程存储在服务器上。

目前,此服务在单独的进程中运行(在清单中使用 android:service=":background")。这使活动和服务之间的通信变得复杂,但我的前辈以这种方式创建应用程序,因为他们认为将服务与活动分开会使它更稳定。

我想要一些更实际的原因来运行一个单独的进程。有什么优势?它真的运行更稳定吗?如果 Service 在单独的进程中,它是否不太可能被操作系统杀死(以释放资源)?

我们的应用程序使用startForeground() 和朋友来最大程度地减少被操作系统杀死的机会。

Android 文档对此不是很具体,主要是说这取决于应用程序的用途 ;-)

TL;DR 将长期运行的服务放在单独的进程中(在 Android 中)的客观原因是什么?

【问题讨论】:

  • 我认为你的意思是 android:process=":background"。我们将服务与活动分开的主要原因是防止可怕的 ANR(活动无响应)。缺点是 IPC 变得有点棘手,并且额外进程的开销。
  • 请注意,通过在最近的应用程序中滑动关闭应用程序也会终止服务,即使它在单独的进程中运行也是如此。这极大地影响了在其服务中运行外部程序的应用程序。 (使用 Android 4.3.1 观察,根据 Freenode 上的#android 似乎是“设计”的。)
  • @Lekensteyn,我的索尼 Xperia M 运行 Android 4.3、5.0 和 5.1 的情况并非如此。你的设备是什么型号的?也许这取决于实现。
  • @sam 这可能是运行 CyanogenMod 的三星 Galaxy S3 (i9300)。
  • @Lekensteyn 知道即使在用户将服务滑开后如何保持服务运行?保持运行;不重启

标签: android process service


【解决方案1】:

减少内存使用

Android 开发者文档建议这可能适合降低服务的 RAM 使用率。

来自Managing Your App's Memory: Use multiple processes

当构建一个音乐播放器以长时间播放来自服务的音乐时,可能适合使用多个进程的一个示例。如果整个应用程序在一个进程中运行,那么只要它正在播放音乐,就必须保留为其活动 UI 执行的许多分配,即使用户当前在另一个应用程序中并且服务正在控制播放。像这样的应用程序可能会分为两个进程:一个用于其 UI,另一个用于在后台服务中继续运行的工作。

因此,在单独的进程中运行服务可以因此降低应用程序的性能影响,同时还可以降低在系统内存不足时服务被终止的可能性。

降低性能影响

来自Managing Your App's Memory: Switching Apps

如果您的应用有一个缓存进程并且它保留了当前不需要的内存,那么您的应用(即使在用户不使用它时)也会限制系统的整体性能。因此,当系统内存不足时,它可能会从最近最少使用的进程开始杀死 LRU 缓存中的进程,但也会考虑哪些进程最占用内存。

被杀的可能性降低

来自Managing Your App's Memory: Release memory as memory becomes tight

注意:当系统开始杀死 LRU 缓存中的进程时,虽然它主要是自底向上工作,但它确实会考虑哪些进程消耗更多内存,从而为系统提供更多如果被杀,内存会增加。因此,您在整个 LRU 列表中消耗的内存越少,您留在列表中并能够快速恢复的机会就越大。

因此,当您的服务位于单独的进程中时,它被杀死的可能性较小,因为该服务不共享 UI 资源,因此该进程的 RAM 使用量会更小。

何时这样做

如果您的服务不使用startForeground(),我发现Android 会在需要释放RAM 时将其杀死,因此服务的RAM 消耗并不太重要。因此,如果您只是考虑对操作系统和其他应用程序的性能影响,我认为不值得在单独的进程中运行该服务。

但是,如果您确实使用startForeground(),Android 会尽量让您的服务保持活动状态,因此进程使用的任何 RAM都会影响操作系统和其他应用程序。所以在这种情况下,我建议使用单独的进程,这样可以节省至少 10MB 的 RAM,这样就不会降低用户设备的速度。

另外,请注意,让您的应用程序实现多进程不容易; Android 的SharedPreferences 不支持多进程。

【讨论】:

  • 当用户在系统中强制关闭应用程序时,如何防止服务被杀死。单独的流程是否允许这样做?
  • @IgorGanapolsky,你的意思是当用户将你的应用从最近的屏幕上滑开时?
  • 没有。当你打开系统设置 -> 你的应用 -> 强制关闭!
  • @IgorGanapolsky,我不知道。
【解决方案2】:

将服务分开在不同的进程中运行并不会使其更稳定,但在某些情况下,会使您的应用程序更稳定,因为如果此服务崩溃,您的应用程序不会随之崩溃,并且可以恢复。

伊莱

【讨论】:

  • 实际上,它确实使服务更稳定,反之亦然:如果应用程序崩溃,服务不会随之崩溃。
  • 如果我使用android关闭应用程序模拟它,应用程序kill也会杀死外部进程。
  • 这是明确杀死应用程序,而不是应用程序崩溃。
  • 如果我没记错的话,当我的应用程序(包含外部服务)崩溃时,它还拖着外部服务(进程)。
  • 我刚刚对此进行了测试,并确认就我而言,主进程崩溃不会影响服务进程。
【解决方案3】:

在自己的进程中运行服务有一个小优点,即服务的垃圾收集器不会影响您的应用程序,并且如果单独运行,服务的内存占用会小一些。

如果您不需要其他应用程序使用该服务,请选择本地服务。或者,您仍然可以在自己的进程中运行服务并与您的应用程序使用不同的通信,例如通过广播接收器。详情请见Android service tutorial

【讨论】:

【解决方案4】:

首先要开始阅读component lifecycles 的描述。从中得出的结论是,您确实不能保证Service 或其他组件将被允许长时间运行。

但是,听起来Service 确实是您描述的功能的正确选择。这是因为您正在执行一些不面向用户的操作。回到生命周期的描述,任何时候一个 Activity 不在前台,它本质上就是一个被杀死的候选者。

您应该考虑使用AlarmManager定期触发您的Service。您可能还想看看使用@CommonsWare 创建的WakefulIntent 库。

在名为Multitasking the Android Way 的 Android 博客上有一篇很好的文章描述了多任务处理和进程,它可能会获得有关您感兴趣的进程的更多详细信息。例如:

一个常见的误解 Android多任务处理是不同的 在进程和应用程序之间。 在 Android 中,这些并不紧密 耦合实体:应用程序可能 似乎没有 当前运行的实际进程 应用程序;多个应用程序可以共享 过程,或一个应用程序可以使 使用多个进程取决于 它的需求;一个或多个过程 应用程序可以通过 Android 即使该应用程序是 不积极做某事。

【讨论】:

  • 感谢您的意见。我已经阅读了生命周期描述(多次),并且我知道没有任何保证。但我想更确切地知道为什么/如何单独的进程可能是有利的,例如操作系统如何决定杀死哪些进程(文档似乎只给出了几个“重要”的例子)。如果它被操作系统杀死,我可以使用 WakefulIntent 重新启动我的服务吗?那会很整洁;-)
  • 是的,AlarmManager 或 WakefulIntent 将启动/重启服务(如果它尚未运行)。
  • 我添加了一篇文章的链接,该链接可能会获得您想要的有关 Android 进程的解释。
  • 我觉得这个答案没有解决核心问题。 OP 已经有一项服务,并且正在讨论它是否应该是一个单独的进程。 AFAICT,这篇文章没有回答这个问题。
  • @Duncan OP 接受了这个作为答案,所以他们一定觉得它确实解决了他们的问题 :)
猜你喜欢
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 2014-04-26
  • 1970-01-01
  • 1970-01-01
  • 2012-03-15
相关资源
最近更新 更多