后台工作概览

应用经常需要同时执行多项操作。Android API 提供了多种不同的方法来实现这一点。选择合适的选项非常重要;一个选项可能适合一种情况,但不适合另一种情况。选择错误的 API 可能会影响应用的性能或资源效率,这可能会消耗电量并降低用户设备的整体性能。在某些情况下,选择错误的方法可能会导致您的应用无法在 Play 商店上架。

本文档介绍了您可以使用的不同选项,并帮助您选择适合您情况的选项。

术语

与后台工作相关的一些重要术语可能会以多种相互矛盾的方式使用。因此,定义术语非常重要。

如果某个应用在后台运行,系统会对其施加很多限制。(例如,在大多数情况下,后台应用无法启动前台服务。)

在本文档中,我们使用“任务”一词来指代应用在主工作流之外执行的操作。为了确保便于理解,我们将这些任务分为三个主要类别的任务类型:异步工作后台工作前台服务

选择合适的选项

在大多数情况下,您可以通过确定任务所属的类别(异步工作后台工作前台服务)来找出适合用于该任务的 API。

如果您仍然不确定,可以使用我们提供的流程图,其中会让决策更细致入微。本文档后面部分将更详细地介绍以上每个选项。

进行后台工作时需要考虑以下两种主要场景:

这两种场景都有自己的决策树。

异步工作

在许多情况下,应用只需在前台运行时执行并发操作。例如,应用可能需要进行一项耗时的计算。如果它在界面线程上执行计算,那么在计算完成之前,用户将无法与应用互动;这可能会导致 ANR 错误。在这种情况下,应用应使用异步工作选项。

常见的异步工作选项包括 Kotlin 协程和 Java 线程;如需了解详情,请参阅异步工作文档。请务必注意,与后台工作不同,当应用停止处于有效的生命周期阶段(例如,应用离开前台)时,异步工作无法保证完成。

后台工作

当您需要执行即使在用户离开应用时也应继续的工作时,后台工作是一种更灵活的选项。在大多数情况下,后台工作的最佳选择是使用 WorkManager,但在某些情况下,可能适合使用平台 JobScheduler API。

WorkManager 是一个功能强大的库,让您可以根据需要设置简单或复杂的作业。您可以使用 WorkManager 调度任务,以便在特定时间运行,也可以指定任务应在哪些条件下运行。您甚至可以设置任务链,让每个任务依次运行,并将其结果传递给下一个任务。如需了解所有可用选项,请仔细阅读 WorkManager 功能列表

以下是一些最常见的后台工作场景:

  • 定期从服务器提取数据
  • 正在提取传感器数据(例如,计步器数据)
  • 获取定期位置数据(在 Android 10 或更高版本上,您必须获得 ACCESS_BACKGROUND_LOCATION 权限)
  • 根据内容触发器上传内容,例如相机创建的照片

前台服务

前台服务提供了一种强大的方法来立即运行不应中断的任务。但是,前台服务可能会给设备带来沉重的负载,有时还会影响隐私和安全。由于这些原因,系统会对应用使用前台服务的方式和时间施加很多限制。例如,前台服务必须能让用户注意到,并且在大多数情况下,当应用在后台运行时无法启动前台服务。如需了解详情,请参阅前台服务文档

创建前台服务的方法有两种。您可以通过调用 Service.startForeground() 声明自己的 Service 并指定该服务是前台服务。或者,您也可以使用 WorkManager 创建前台服务,如对长时间运行的 worker 的支持中所述。 但请务必注意,WorkManager 创建的前台服务必须遵循与任何其他前台服务一样的所有限制。WorkManager 只是提供了一些便捷 API,可让您更轻松地创建前台服务。

替代 API

系统提供了一些备选 API,这些 API 旨在针对更具体的用例实现更好的效果。如果有适用于您的用例的替代 API,我们建议您使用该 API 而不是前台服务,因为这有助于提升应用的性能。前台服务类型文档指出了何时有好的替代 API 可以用来代替特定的前台服务类型。

以下是一些使用替代 API 的最常见场景:

用户启动的任务

展示如何选择适当 API 的流程图。此图表汇总了“用户发起的任务”部分中的材料。
图 1:如何选择正确的 API 来运行用户发起的后台任务。

如果应用需要执行后台工作,并且操作是在应用可见时由用户启动的,请回答以下问题以找到合适的方法。

当应用在后台运行时,任务是否需要继续运行?

如果应用在后台运行时任务不需要继续工作,您应使用异步工作。有很多选项可用于执行异步工作。请务必了解,如果应用进入后台,这些选项都会停止运行。(如果应用关闭,这些测试也会停止。)例如,社交媒体应用可能需要刷新其内容 Feed,但如果用户离开屏幕,就不需要完成操作。

如果任务延迟或中断,是否会导致糟糕的用户体验?

请务必考虑如果任务被推迟或取消,用户体验是否不会受到负面影响。例如,如果应用需要更新其资源,用户可能不会注意到操作是立即发生,还是发生在午夜设备充电时。在这种情况下,您应该使用后台工作选项。

这是一项简短的关键任务吗?

如果任务无法延迟并且将快速完成,您可以使用 shortService 类型的前台服务。这些服务比其他前台服务更容易创建,并且不需要太多权限。但是,短期服务必须在三分钟内完成。

有没有专门用于此用途的替代 API?

如果任务对用户不可见,正确的解决方案可能是使用前台服务。这些服务在启动后会持续运行,因此如果中断任务会给用户带来糟糕的体验,则使用这些服务是不错的选择。例如,锻炼跟踪应用可能会使用位置传感器来让用户在地图上记录其慢跑路线。您不应使用后台工作选项执行此操作,因为如果任务被暂停,跟踪将立即停止。在这种情况下,前台服务最为合理。

不过,由于前台服务可能会使用大量的设备资源,因此系统会对使用时间和方式施加很多限制。在许多情况下,您可以不使用前台服务,而是使用一个替代 API 来为您处理作业,从而更轻松地处理作业。例如,如果您的应用需要在用户到达特定位置时执行某项操作,那么最好的选择是使用地理围栏 API,而不是使用前台服务跟踪用户的位置。

响应事件的任务

展示如何选择适当 API 的流程图。此图表总结了“通过任务响应活动”部分中的材料。
图 2:如何为运行事件触发的后台任务选择正确的 API。

有时,应用需要执行后台工作来响应触发器,例如:

这可能是外部触发器(如 FCM 消息),也可能是响应应用本身设置的闹钟。例如,游戏可能会收到一条 FCM 消息,告知它更新一些资源。

如果您确定任务将在几秒钟内完成,请使用异步工作执行该任务。系统将给您的应用留出几秒钟的时间来执行任何此类任务,即使您的应用在后台运行也是如此。

如果完成任务所需的时间超过几秒,建议启动一个前台服务来处理任务。事实上,如果任务由用户触发并且属于已获批准的后台启动限制豁免之一,那么即使您的应用当前在后台运行,也可能允许启动前台服务。例如,如果应用收到高优先级 FCM 消息,即使应用在后台运行,也可以启动前台服务。

如果任务需要的时间超过几秒钟,请使用后台工作