WorkManager 能做什么
WorkManager 是 Android 官方后台任务框架,专门处理"需要保证执行"的任务:上传日志、同步数据、清理缓存。系统会挑合适的时间运行,应用被杀、设备重启后任务依然会补执行。
能等、必须完成的活,交给 WorkManager。
基础用法是继承 Worker 写 doWork,再 WorkManager.getInstance().enqueue 一次性的 OneTimeWorkRequest。这篇在基础之上讲进阶:约束条件、周期任务、链式任务、唯一工作,以及怎么观察任务进度。
先把概念理清:任务分一次性(OneTime)和周期(Periodic);任务之间可以串成链,前一个成功才跑后一个;同名任务可以设成唯一,重复提交自动合并。掌握这三个维度,后台任务基本就排明白了。
约束条件 Constraints
约束决定任务什么时候能跑:要求网络已连接、正在充电、存储空间充足,或者设备空闲。约束不满足时任务排队等待,满足后自动执行。
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(true)
.setRequiresStorageNotLow(true)
.build()
val request = OneTimeWorkRequestBuilder<SyncWorker>()
.setConstraints(constraints)
.build()
- NetworkType不限/联网/非计费网络。
- Charging是否要求充电中。
- Idle是否要求设备空闲。
周期任务与退避策略
周期任务用 PeriodicWorkRequest,最短间隔十五分钟,适合定期同步、定期清理。注意周期任务不支持链式依赖,且第一次执行就有间隔等待。
val periodic = PeriodicWorkRequestBuilder<CleanWorker>(
1, TimeUnit.HOURS
).setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30, TimeUnit.SECONDS)
.build()
WorkManager.getInstance(context).enqueue(periodic)
任务失败重试时按退避策略等待:线性(LINEAR)每次加固定时间,指数(EXPONENTIAL)时间翻倍。别用默认值裸奔,设置一个合理的初始等待,避免失败后疯狂重试打爆服务器。
链式任务与唯一工作
多个任务按顺序执行用 beginWith 串链:下载完成才解压,解压完成才入库。链上任何一环失败,后续默认取消。
WorkManager.getInstance(context)
.beginWith(downloadRequest)
.then(unzipRequest)
.then(importRequest)
.enqueue()
唯一工作用 beginUniqueWork 加名字:同样名字的任务已经在跑,新提交的要么排队、要么替换、要么忽略,由 ExistingWorkPolicy 决定。上传用户头像这种场景,重复提交就该用 REPLACE,别让两次上传打架。
观察任务状态与进度
任务的 WorkInfo 带着状态:ENQUEUED、RUNNING、SUCCEEDED、FAILED。用 LiveData 或 Flow 观察,可以实时拿到进度并刷新 UI。
WorkManager.getInstance(context)
.getWorkInfoByIdLiveData(requestId)
.observe(this) { info ->
val progress = info?.progress?.getInt("pct", 0)
binding.progressBar.progress = progress ?: 0
}
Worker 里用 setProgress 上报进度,UI 端观察即可。注意 WorkInfo 只在任务有对应状态时发数据,进度更新会触发新的发射,别在观察者里做重活。
实战:图片同步任务链
做一个图片备份链:联网且充电时,先下载待同步清单,再逐张上传,最后清理本地临时文件。
val chain = WorkManager.getInstance(context)
.beginUniqueWork("photo-sync", ExistingWorkPolicy.REPLACE,
OneTimeWorkRequestBuilder<FetchListWorker>()
.setConstraints(networkAndCharging)
.build())
.then(OneTimeWorkRequestBuilder<UploadWorker>().build())
.then(OneTimeWorkRequestBuilder<CleanWorker>().build())
chain.enqueue()
上传 Worker 里 setProgress 上报每张进度,通知栏或页面显示百分比。任务失败时检查 WorkInfo 的 outputData,把错误原因带给 UI 展示。
小结
WorkManager 进阶四件套:约束定时机、退避控重试、链式定顺序、唯一防重复。周期任务管定期活,WorkInfo 管进度条。把后台任务当成一条流水线来设计,每一步有约束、有依赖、有反馈,系统再忙也能跑得明明白白。