WorkManager 是一个 API,可供您轻松调度那些即使在退出应用或重启设备后仍应运行的可靠异步任务。
WorkManager 适用于需要可靠运行的工作,即使用户导航离开屏幕、退出应用或重启设备也不影响工作的执行。例如:
- 向后端服务发送日志或分析数据
- 定期将应用数据与服务器同步
简言之,WorkManager 用于执行后台任务。
优势:
- 使用工作约束明确定义工作运行的最佳条件。工作约束有电量充足、联网约束(如仅Wifi情况)、设备空闲等。
- 调度灵活。可以执行一次或周期性任务,可对任务添加标记,可取消任务。
- 灵活的重试策略。任务执行失败的话可选择重试。
- 工作链。对于多个任务,可以约定任务的先后执行关系。
开始使用,
1.添加依赖
dependencies {
def work_version = "2.5.0"
// WorkManager
implementation "androidx.work:work-runtime:$work_version"
}
2.自定义Worker
自定义一个任务,继承 Worker ,重写 doWork() 方法,doWork() 方法中实现具体的后台任务逻辑。
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
class MyWorker(context: Context, parameters: WorkerParameters) : Worker(context, parameters) {
override fun doWork(): Result {
//TODO("Not yet implemented")
// do really work
return Result.success()
}
}
doWork() 返回的 Result 结果有:
- Result.success():工作成功完成。
- Result.failure():工作失败。
- Result.retry():工作失败,可根据配置的重试策略在其他时段重试。
3.创建请求 WorkRequest
使用 OneTimeWorkRequest 创建单次运行的后台任务请求,
var request = OneTimeWorkRequest.Builder(MyWorker::class.java).build()
可以添加 标签和 其他约束条件,
var request = OneTimeWorkRequest
.Builder(MyWorker::class.java)
//10分钟后执行
.setInitialDelay(10, TimeUnit.MINUTES)
// 标签设为 tag_request ,可根据标签取消任务
.addTag("tag_request")
// 结合 Result.retry() 使用,任务失败重新执行任务,
//任务实行失败的话, 60 秒后重试,再次失败的话,下次重试的时间间隔线性增加(也可以设置成指数性(BackoffPolicy.EXPONENTIAL)增加)
.setBackoffCriteria(BackoffPolicy.LINEAR, 60, TimeUnit.SECONDS)
.build()
如果设置了 setBackoffCriteria ,可以根据任务的 id 来监听任务执行结果,
WorkManager.getInstance(this).getWorkInfoByIdLiveData(request.id)
.observe(this){ workInfo ->
if (workInfo.state == WorkInfo.State.SUCCEEDED) {
} else if (workInfo.state == WorkInfo.State.FAILED) {
}
}
4.将 WorkRequest 提交给系统
很简单,这样就提交给系统了,系统会在合适的时机执行。
WorkManager.getInstance(this).enqueue(request)
5.工作链
有多个任务的话,可以约束他们的先后执行关系,
val request1 = OneTimeWorkRequest.Builder(MyWorker::class.java).addTag("request1").build()
val request2 = OneTimeWorkRequest.Builder(MyWorker::class.java).addTag("request2").build()
val request3 = OneTimeWorkRequest.Builder(MyWorker::class.java).addTag("request3").build()
WorkManager.getInstance(this)
.beginWith(request1)
.then(request2)
.then(request3)
.enqueue()
先执行 request1 ,再执行 request2 ,然后执行 request3 。如果 request1 执行失败,request2 和 request3 就不会执行。
6.取消任务
根据 id 取消单个任务
WorkManager.getInstance(this).cancelWorkById(request.id)
根据 tag 取消此 tag 下的所有任务
WorkManager.getInstance(this).cancelAllWorkByTag("tag_request")
取消所有任务
WorkManager.getInstance(this).cancelAllWork()