后台任务概述

应用通常需要同时执行多个操作。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。

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

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

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

如果任务被延迟或中断,用户体验是否会变差?

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

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

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

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

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

但是,由于前台服务可能会使用大量设备资源,因此系统对何时以及如何使用它们施加了许多限制。在许多情况下,您可以使用替代 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