WorkManager 是什么?我们先聊聊背景
说实话,刚接触 Android 后台任务那会儿,我也挺头疼的。
你想象一下:用户切到后台,你的 App 想做个上传,结果进程被系统杀了。或者你用了 Service,结果在 Android 8 以上直接被限制。嗯,这种问题我在项目中遇到过不止一次。
WorkManager 就是 Google 给出的官方答案。它不是简单的「定时器」,也不是另一个 Service 封装。说白了,它是 Android 平台的后台任务指挥官——帮你搞定兼容性、电量优化、甚至进程保活这些破事。
为什么 Android 需要 WorkManager?
- 兼容性噩梦:不同厂商、不同 Android 版本的后台策略差异巨大。我记得在某个国产手机上,JobScheduler 几乎失效,换成 WorkManager 才跑通。
- 电池优化:Doze 模式、App Standby,系统越来越严格。WorkManager 会自动选择最佳执行时机。
- 任务可靠性:即使 App 被杀死、设备重启,WorkManager 也能把任务捡回来接着干。
| 对比项 | Service | JobScheduler | WorkManager |
|---|---|---|---|
| 进程存活 | 需前台通知 | 系统调度 | 自动管理 |
| 重启恢复 | 不支持 | 部分支持 | 内置支持 |
| 电量优化 | 无 | 良好 | 优秀 |
| 兼容性 | 差 | 中 | 好 |
我个人的建议:只要不是必须立即执行的 UI 操作,优先用 WorkManager。它帮你处理了 80% 的兼容陷阱。
WorkManager 的核心组件
理解 WorkManager,其实只需要记住四个东西:
- Worker —— 你写逻辑的地方。继承 Worker 类,在
doWork()里干活。 - WorkRequest —— 任务请求。告诉系统「我要干什么、什么条件下干」。分
OneTimeWorkRequest和PeriodicWorkRequest。 - WorkManager —— 调度中心。它负责排队、约束检查、重试策略。
- WorkContinuation —— 任务链。把多个任务串起来,或并行、或顺序执行。
举个最简单的例子:
class UploadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
// 这里写你的上传逻辑
return Result.success()
}
}
val uploadRequest = OneTimeWorkRequestBuilder<UploadWorker>()
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
)
.build()
WorkManager.getInstance(context).enqueue(uploadRequest)
你看,三行代码就把「有网才执行」的后台任务安排上了。我在项目里经常用这种方式来管理日志上传、图片同步这类需求。
WorkManager 的关键特性
- 保证执行:就算 App 被关、设备重启,任务也不会丢。它基于 Room 数据库持久化任务状态。
- 约束条件:网络、电量、存储空间、空闲状态……你可以任意组合。
- 优先级与任务链:这是本课程的核心。WorkManager 支持为任务设置
workScheduler的优先级(实际上是通过setBackoffCriteria、setInitialDelay和任务链顺序来控制)。 - 观察任务状态:返回
LiveData或ListenableFuture,方便 UI 层响应。
曾经有个坑:我刚开始用 WorkManager 时,以为
PeriodicWorkRequest 是最短 15 分钟执行一次。结果它在某些定制 ROM 上,最短间隔被拉长到 30 分钟甚至 1 小时。所以如果你的业务要求精确周期,建议用 OneTimeWorkRequest 配合 setInitialDelay 自己循环调度。
本章知识体系结构图
下面这张图帮你理清 WorkManager 的基本脉络。别被名字吓到,它就是个后台任务管家。
一句话总结本章:WorkManager 是 Android 官方推荐的、兼容性最好的后台任务管理工具。它通过 Worker + WorkRequest + Constraints 这套组合拳,帮你写出可靠、能逃过系统限制的后台代码。
我见过一些团队把 Service、JobScheduler、AlarmManager 混着用,结果维护起来相当痛苦。换成 WorkManager 后,代码量直接少了一半,崩溃率也降了。
嗯,接下来的章节我们会深入 优先级 这个主题——为什么默认的调度方式会引发帧率抖动?怎么用 Backoff 策略和任务链来「调教」它?