为什么需要后台任务
应用退到后台,系统会随时回收进程。想在后台同步数据、上传日志、定时更新,得有一套不被轻易杀掉的机制。WorkManager 就是干这个的。它替你管着任务的生命周期,进程死了任务还在,设备重启了任务照样会被重新拉起来,你不用自己和系统的省电策略硬碰硬。
任务不该盯着用户开不开应用,该在系统合适时自己跑。
这篇把 WorkManager 走一遍。
WorkManager 是什么
WorkManager 是官方推荐的后台任务调度器。你定义任务和约束,它选系统最合适的时机跑,应用关了、设备重启了任务也不丢。它在底层会根据安卓版本自动选最合适的实现,你不用关心是用了作业调度还是前台服务。
WorkManager 速查
- 任务继承 Worker,在后台干活。
- 约束联网、充电、空闲才跑。
- 持久重启不丢,失败自动重试。
定义一个任务
继承 Worker,在 doWork 里干活,返回成功或重试。
class UploadWorker(ctx: Context, p: WorkerParameters)
: Worker(ctx, p) {
override fun doWork(): Result {
uploadLogs()
return Result.success()
}
}
任务体就是一个 doWork。它在后台线程执行,别在里面碰界面,跑完返回结果就行。需要传参数就用 Data 打包,结果也用 Data 带回来。
约束条件
给任务加约束:只有联网才跑、只有充电才跑。不满足就等,满足了系统自动调度。
持久任务与重试
WorkManager 的任务是持久化的:应用进程死了、设备重启了,任务照样会被重新调度。失败返回 Result.retry,它按退避策略再试。
任务链与观察结果
任务可以串成链:先压缩再上传。用 WorkInfo 观察任务状态,跑成功了更新界面。
- 约束写清楚再提交。
- 失败用退避重试。
- 观察状态驱动界面。
实战:联网时上传日志
只在联网时上传日志。
val req = OneTimeWorkRequestBuilder<UploadWorker>()
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build())
.build()
WorkManager.getInstance(ctx).enqueue(req)
一联网它就自动上传,不用用户盯着。后台活儿做到这份上,应用在后台也稳。