应用经常需要同时执行多项操作。Android API 提供了许多不同的方法来实现此目的。选择正确的选项非常重要;某个选项可能适合一种情况,但可能非常不适合另一种情况。选择错误的 API 可能会损害应用的性能或资源效率,从而耗尽电池电量并降低用户设备的整体性能。在某些情况下,选择错误的方法可能会导致您的应用无法在 Play 商店中上架。
本文档介绍了您可以使用的不同选项,并帮助您选择适合您情况的选项。
术语
与后台任务相关的一些重要术语可能会以多种相互矛盾的方式使用。因此,明确定义我们的术语非常重要。
如果应用在后台运行,系统会对其施加一些限制。(例如,在大多数情况下,后台应用无法启动前台服务。)
在本文档中,我们将使用“任务”一词来表示应用在其主工作流之外执行的操作。为了确保理解一致,我们将其分为三大类任务类型:异步工作、任务调度 API 和前台服务。
选择合适的选项
在大多数情况下,您可以通过确定任务所属的类别(异步工作、任务调度 API 或前台服务)来确定适合该任务的 API。
如果您仍不确定,可以使用我们提供的流程图,其中添加了更多细微差别。本文档后面部分会更详细地介绍其中每个选项。
对于后台任务,需要考虑以下两种主要场景:
这两种情况有各自的决策树。
异步工作
在许多情况下,应用只需在前台运行时执行并发操作。例如,应用可能需要执行耗时的计算。如果它在界面线程上执行计算,则用户在计算完成之前将无法与应用互动;这可能会导致 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 的一些最常见场景包括:
由用户发起的任务
如果应用需要执行后台任务,并且该操作是由用户在应用可见时发起的,请回答以下问题,找到合适的方法。
在应用处于后台时,任务是否需要继续运行?
如果任务在应用处于后台时不需要继续运行,您应使用异步工作。有多种方法可以执行异步工作。需要了解的重要一点是,如果应用进入后台,这些选项都会停止运行。 (如果应用关闭,这些任务也会停止。)例如,社交媒体应用可能需要刷新其内容 Feed,但如果用户离开屏幕,则无需完成该操作。
如果任务被推迟或中断,是否会造成糟糕的用户体验?
请务必考虑,如果任务被推迟或取消,用户体验是否会受到损害。例如,如果应用需要更新其资源,用户可能不会注意到该操作是立即发生,还是在设备充电时在深夜发生。在这种情况下,您应使用后台工作选项。
是否是短期的重要任务?
如果任务无法延迟且会快速完成,您可以使用类型为 shortService 的前台服务。这些服务比其他前台服务更容易创建,并且不需要太多权限。不过,短服务必须在 3 分钟内完成。
是否有专门用于此目的的替代 API?
如果任务对用户可见,正确的解决方案可能是使用前台服务。这些服务在启动后会持续运行,因此如果中断任务会带来糟糕的用户体验,那么这些服务是不错的选择。例如,锻炼跟踪应用可能会使用位置传感器,让用户在地图上记录其慢跑路线。您不希望通过后台工作选项执行此操作,因为如果任务暂停,跟踪会立即停止。在这种情况下,前台服务最合适。
不过,由于前台服务可能会使用大量设备资源,因此系统对前台服务的使用时间和使用方式施加了许多限制。在许多情况下,您可以使用替代 API 来处理作业,而无需使用前台服务,这样可以减少麻烦。例如,如果您的应用需要在用户到达特定位置时执行某项操作,则最好使用地理围栏 API,而不是使用前台服务跟踪用户的位置。
为响应事件而执行的任务
有时,应用需要执行后台工作来响应触发器,例如:
这可能是外部触发器(例如 FCM 消息),也可能是对应用本身设置的闹钟的响应。例如,游戏可能会收到一条 FCM 消息,告知其更新某些资源。
如果您可以确定任务将在几秒钟内完成,请使用异步工作来执行任务。系统会允许您的应用在几秒钟内执行任何此类任务,即使您的应用在后台运行也是如此。
如果任务需要几秒钟以上的时间,则可能适合启动前台服务来处理该任务。事实上,即使您的应用当前在后台运行,如果任务是由用户触发的,并且属于后台启动限制的某个已获批准的豁免情况,则该应用可能仍可以启动前台服务。例如,如果应用收到高优先级 FCM 消息,则即使应用在后台运行,也允许启动前台服务。
如果任务需要几秒钟以上的时间,请使用任务调度 API。