简介
WorkManager适合处理一些定时执行的任务,它可以根据操作系统的版本自动选择底层是使用AlarmManager实现还是JobScheduler,降低我们的使用成本,同时他还支持周期性任务、链式任务处理等功能。
WorkManager可以在应用退出或者手机重启的情况下,还能够执行之前注册的任务
主要功能
添加网络可用性或充电状态等工作约束
调度一次性或周期性异步任务
监控和管理计划任务
将任务链接起来
确保任务执行,即使应用或设备重启也同样执行任务
遵循低电耗模式等省电功能
使用
在build.gradle中引入依赖
dependencies {
...
implementation 'androidx.work:work-runtime:2.3.0'
}
创建WorkManager后台任务
class WorkManagerTest(context: Context, workerParams: WorkerParameters) : Worker(
context,
workerParams
) {
// 该方法在WorkManager提供的后台线程上同步运行
override fun doWork(): Result {
Log.e("WorkManagerTest", "do work in workmanager")
// 返回结果表示任务运行结果,
return Result.success()
}
}
配置约束条件并调用后台任务
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
doWork.setOnClickListener {
// 构建单次运行的后台任务请求
val request = OneTimeWorkRequest.Builder(WorkManagerTest::class.java).build()
// 构建周期性运行的后台任务请求, 为了降低设备的性能功耗,运行周期间隔不得少于15分钟
val request1 =
PeriodicWorkRequest.Builder(WorkManagerTest::class.java, 15, TimeUnit.MINUTES)
.build()
// 系统在合适的时间调用两个后台任务
WorkManager.getInstance(this).enqueue(request)
WorkManager.getInstance(this).enqueue(request1)
}
}
}
高级特性
1. 创建后台任务请求时建立约束
val request = OneTimeWorkRequest.Builder(WorkManagerTest::class.java)
.setInitialDelay(5, TimeUnit.MINUTES) // 让任务在指定延时后执行
.addTag("test") // 添加请求标签,并可以通过WorkManager.getInstance(this).cancelAllWorkByTag("test") 取消任务
.setBackoffCriteria(
BackoffPolicy.LINEAR,
10,
TimeUnit.SECONDS
) // 如果任务返回result.retry(), 可以通过该函数进行重试,第一个参数表示再次失败后延迟执行的形式,LINEAR表示线性延迟, EXPONENTIAL表示指数方式延迟,第二第三个参数表示指定在多久之后重新执行任务,不得少于10秒
.build()
2. 监听后台任务的状态变化
// 监听后台任务的状态变化
WorkManager.getInstance(this).getWorkInfoByIdLiveData(request.id)
.observe(this, Observer { workInfo ->
if (workInfo.state == WorkInfo.State.SUCCEEDED) {
Log.e("MainActivity", "Work Successed")
} else if (workInfo.state == WorkInfo.State.FAILED) {
Log.e("MainActivity", "Work Failed")
}
})
3. 任务的链式调用
// WorkManager链式调用
WorkManager.getInstance(this)
// Candidates to run in parallel
.beginWith(download)
// Dependent work (only runs after all previous work in chain)
.then(compress)
.then(upload)
// Don't forget to enqueue()
.enqueue()
4. 取消任务
// 通过id取消任务
WorkManager.getInstance(this).cancelWorkById(request.id)
// 通过tag取消任务
WorkManager.getInstance(this).cancelAllWorkByTag("test")