后台任务概览

应用经常需要同时执行多项操作。Android API 提供了许多不同的方法来让您实现此目的。选择正确的选项非常重要;某个选项可能适用于某种情况,但对另一种情况却非常不适用。选择错误的 API 可能会损害您的应用性能或资源效率,从而耗尽电池并降低用户设备的整体性能。在某些情况下,选择错误的方法可能会导致您的应用无法在 Play 商店中上架。

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

术语

某些与后台任务相关的重要术语可能会以多种相互矛盾的方式使用。因此,明确我们的术语非常重要。

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

就本文档而言,我们将“任务”一词定义为应用在其主要工作流之外执行的操作。为了确保理解上的一致性,我们将其分为三大类任务:异步工作任务调度 API前台服务

选择正确的选项

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

如果您仍然不确定,可以使用我们提供的流程图,这些流程图为决策增添了更多细微差别。本文档后面将更详细地介绍这些选项。

后台任务需要考虑的两种主要情况

这两种情况都有自己的决策树。

异步工作

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

常见的异步工作选项包括 Kotlin 协程和 Java 线程;您可以在异步工作文档中找到更多信息。请务必注意,与后台任务 API 不同,如果应用不再处于有效的生命周期阶段(例如,如果应用离开前台),异步工作不保证完成。

任务调度 API

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

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

一些最常见的后台任务场景包括

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

前台服务

前台服务提供了一种强大的方式来立即运行不应中断的任务。然而,前台服务可能会对设备造成沉重负担,有时还会涉及隐私和安全问题。因此,系统对应用如何以及何时可以使用前台服务施加了许多限制。例如,前台服务必须对用户可见,并且在大多数情况下,当应用处于后台时,应用无法启动前台服务。如需了解详情,请参阅前台服务文档

创建前台服务有两种方法。您可以声明自己的 Service,并通过调用 Service.startForeground() 将该服务指定为前台服务。此外,您还可以使用 WorkManager 创建前台服务,如支持长时间运行的工作器中所述。但是,请务必了解,WorkManager 创建的前台服务必须遵守与任何其他前台服务相同的限制。WorkManager 只是提供了一些便捷 API,以便更简单地创建前台服务。

替代 API

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

使用替代 API 的一些最常见场景包括

用户发起的任务

Flowchart showing how to choose the appropriate API. This chart
  summarizes the material in the section 'Tasks initiated by the user'.
图 1:如何为运行用户发起的后台任务选择正确的 API。

如果应用需要执行后台任务,并且该操作是在应用可见时由用户发起的,请回答以下问题以找到正确的方法。

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

如果任务不需要在应用处于后台时继续运行,则应使用异步工作。有多种选项可用于执行异步工作。需要理解的重要一点是,如果应用进入后台,这些选项都会停止运行。(如果应用关闭,它们也会停止运行。)例如,社交媒体应用可能希望刷新其内容 Feed,但如果用户离开屏幕,则不需要完成该操作。

如果任务被推迟或中断,用户体验会受到影响吗?

考虑任务被推迟或取消是否会损害用户体验非常重要。例如,如果应用需要更新其资源,用户可能不会注意到操作是立即发生,还是在设备充电的深夜发生。在这种情况下,您应该使用后台工作选项。

是短期、关键任务吗?

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

是否有专门为此目的的替代 API?

如果任务对用户可见,正确的解决方案可能是使用前台服务。这些服务一旦启动就会持续运行,因此在中断任务会带来糟糕用户体验的情况下,它们是很好的选择。例如,健身追踪应用可能会使用位置传感器让用户在地图上记录其慢跑路线。您不会希望使用后台工作选项来执行此操作,因为如果任务暂停,追踪会立即停止。在这种情况下,前台服务最有意义。

然而,由于前台服务可能会占用大量设备资源,系统对它们的使用时间和方式施加了许多限制。在许多情况下,您可以使用替代 API 来处理工作,而不是使用前台服务,这样可以减少麻烦。例如,如果您的应用需要在用户到达某个特定位置时执行操作,则最佳选择是使用地理围栏 API,而不是使用前台服务追踪用户位置。

响应事件的任务

Flowchart showing how to choose the appropriate API. This chart
  summarizes the material in the section 'Tasks in response to an event'.
图 2:如何为运行事件触发的后台任务选择正确的 API。

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

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

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

如果任务需要几秒钟以上的时间,则可能适合启动前台服务来处理任务。实际上,即使您的应用当前在后台运行,如果任务是由用户触发并属于经批准的后台启动限制豁免之一,也可能允许它启动前台服务。例如,如果应用收到高优先级 FCM 消息,即使应用在后台运行,也允许它启动前台服务。

如果任务需要几秒钟以上的时间,请使用任务调度 API