后台处理指南

每个 Android 应用都有一个主线程,负责处理界面(包括测量和绘制视图)、协调用户互动以及接收生命周期事件。如果有太多工作在主线程中进行,则应用可能会挂起或运行速度变慢,从而导致用户体验不佳。任何长时间运行的计算和操作(例如解码位图、访问磁盘或执行网络请求)都应在单独的后台线程上完成。一般来说,任何所需时间超过几毫秒的任务都应该分派到后台线程。在用户与应用积极互动时,可能需要执行几项这样的任务。要了解如何在用户积极使用应用时在后台线程而非主界面线程上运行任务,请查看线程处理解决方案指南

即使在用户没有积极使用应用时,应用可能也需要运行一些任务(例如,定期与后端服务器同步或定期从应用内提取新内容)。即使在用户完成与应用的互动后,应用可能也需要立即运行一些服务至结束。本指南将帮助您了解在这些使用情形下哪种解决方案最能满足您的需求。

后台处理面临的挑战

后台任务会使用设备的有限资源,例如 RAM 和电池电量。如果处理不当,可能会导致用户体验不佳。

为了最大限度地延长电池续航时间并强制推行良好的应用行为,Android 会在应用(或前台服务通知)对用户不可见时,限制后台工作。

  • Android 6.0(API 级别 23)引入了低电耗模式和应用待机模式。低电耗模式会在屏幕处于关闭状态且设备处于静止状态时限制应用行为。应用待机模式会将未使用的应用置于一种特殊状态,进入这种状态后,应用的网络访问、作业和同步会受到限制。
  • Android 7.0(API 级别 24)限制了隐式广播,并引入了随时随地使用低电耗模式
  • Android 8.0(API 级别 26)进一步限制了后台行为,例如在后台获取位置信息和释放缓存的唤醒锁定。
  • Android 9(API 级别 28)引入了应用待机存储分区,通过它,系统会根据应用使用模式动态确定应用资源请求的优先级。

请务必了解您的任务需求并选择合适的解决方案,以便根据系统最佳做法安排后台作业。

为您的工作选择合适的解决方案

  • 工作可以延迟,还是需要立即执行?例如,如果您需要从网络中提取一些数据以对用户点击按钮的操作作出响应,则必须立即执行该工作。但是,如果您希望将日志上传到服务器,则可以延迟执行该工作,而不会影响应用的性能或用户期望。

  • 工作是否依赖系统条件?您可能希望仅在设备满足特定条件(例如连接到电源、连接到互联网等)时运行作业。例如,您的应用可能需要定期压缩存储的数据。为避免对用户造成影响,您会希望仅在设备充电和处于闲置状态时运行该作业。

  • 作业是否需要在确切的时间运行?日历应用可能会允许用户为事件设置在特定时间触发的提醒。用户希望在正确的时间看到提醒通知。在其他情况下,应用可能不会关注作业的确切运行时间。应用可能会有常规要求,例如“必须先运行作业 A,然后运行作业 B、作业 C”,但不要求作业在特定时间运行。

图 1. 执行后台工作的最佳方式是什么?

WorkManager

对于可延迟的工作以及预计即使您的设备或应用重启也会运行的工作,请使用 WorkManager。WorkManager 是一个 Android 库,可在满足工作的条件(例如网络可用性和电源)时妥善运行可延迟的后台工作。

WorkManager 提供向后兼容的 API(兼容 API 级别 14 及更高级别),利用 JobScheduler API(API 级别 23 及更高级别)帮助优化更低级别设备上的电池续航时间、批量作业以及 AlarmManagerBroadcastReceiver 的组合。

前台服务

对于需要立即运行并且必须执行完毕的由用户发起的工作,请使用前台服务。使用前台服务可告知系统应用正在执行重要任务,不应被终止。前台服务通过通知栏中的不可关闭通知向用户显示。

AlarmManager

如果您需要在确切的时间运行某项作业,请使用 AlarmManagerAlarmManager 会在您指定的时间启动应用(如有必要),以便运行该作业。但是,如果您的作业不需要在确切的时间运行,则 WorkManager 是更好的选择;WorkManager 能更好地平衡系统资源。例如,如果您需要大约每小时运行一次某项作业,但不需要在特定时间运行该作业,则应使用 WorkManager 设置周期性作业。

DownloadManager

如果您的应用执行长时间运行的 HTTP 下载,请考虑使用 DownloadManager。客户端可能会请求将 URI 下载到位于应用进程之外的特定目标文件中。内容下载管理器会在后台执行下载操作,它负责处理 HTTP 互动,在下载失败或连接发生更改以及系统重新启动后重新尝试下载。