持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情
Jetpeck从入门到几乎入门(五)
前言
Jetpack系列:
Jetpack从入门到几乎入门(一) - 掘金 (juejin.cn)
Jetpack从入门到几乎入门(二) - 掘金 (juejin.cn)
Jetpack从入门到几乎入门(三) - 掘金 (juejin.cn)
本文是我在学习guolin大神的《第一行代码》第三版Jetpack部分的Room的知识总结,文中部分代码参考自《第一行代码》第三版
在阅读本文前,您需要掌握kotlin语言的基本语法,并且了解什么是LifeCycle
帮助编写后台代码的组件——WorkManager
简介
不知从何时开始,与后台相关的API变更越来越频繁,为了使后台代码能在不同系统版本上保证兼容性,Google 推出了WorkManager
组件。
WorkManager
适合用于处理一些要求定时执行的任务,它可以根据操作系统的版本自动选择底层是使用AlarmManager
实现还是JobScheduler
实现。
与AsyncTask, ThreadPool, RxJava的不同
使用这三个工具确实能帮助我们在后台线程实现一些功能,不过应用一被杀掉就干不了活了。WorkManager
的不同之处在于,它在应用被杀, 甚至设备重启后仍能保证任务的执行。这一特性也决定了它的应用场景,WorkManager
适合处理那些必须完成并且可以延迟的后台工作。
WorkManager的使用
首先在app/build.gradle 文件中添加依赖
dependencies {
def work_version = "1.0.0-beta02"
implementation "android.arch.work:work-runtime-ktx:$work_version"
}
在依赖添加完成后,我们先添加一个任务。我们先创建一个SimpleWorker
类。
class SimpleWorker(context: Context,params: WorkerParameters):Worker(context,params) {
//doWork()方法不会运行在主线程中,我们可以放心实现各种逻辑
override fun doWork(): Result {
Log.d("SimpleWorker", "do work in SimpleWorker")
return Result.success()//返回示任务的运行结果
}
}
每个后台任务都必须继承Worker类,我们可以在doWork()
方法中编写后台任务的逻辑。
在定义好后台任务后,我们可以配置该后台任务的运行条件。
在Activity中配置
binding.doWorkBtn.setOnClickListener{
//val request = OneTimeWorkRequest.Builder(SimpleWorker::class.java).build()//单次任务请求
val request = PeriodicWorkRequest.Builder(SimpleWorker::class.java, 15,
TimeUnit.MINUTES).build()//构造函数中传入的运行周期间隔不能短于15 分钟
}
PeriodicWorkRequest.Builder,可用于构建周期性运行的后台任务请求。
最后,将后台任务传入WorkManager的enqueue()方法中
WorkManager.getInstance(context).enqueue(request)
用WorkManager处理复杂的任务
让后台任务在指定的延迟时间后运行
需借助setInitialDelay()
方法
val request = OneTimeWorkRequest.Builder(SimpleWorker::class.java)
.setInitialDelay(5,TimeUnit.MINUTES)
.build()
我们还可以给后台任务请求添加标签
val request = OneTimeWorkRequest.Builder(SimpleWorker::class.java)
.setInitialDelay(5,TimeUnit.MINUTES)
.addTag("simple")
.build()
在没有标签时,可以通过id来取消后台任务请求,使用标签后不仅可以取消单个任务,还可以将同一标签名的所有后台任务请求全部取消:
WorkManager.getInstance(this).cancelWorkById(request.id)//通过ID
WorkManager.getInstance(this).cancelAllWorkByTag("simple")//通过标签
WorkManager.getInstance(this).cancelAllWork()//一次性取消所有请求
doWork()方法中返回了Result.retry()后,可以通过setBackoffCriteria()方法来重新执行任务
val request = OneTimeWorkRequest.Builder(SimpleWorker::class.java)
...
.setBackoffCriteria(BackoffPolicy.LINEAR, 10, TimeUnit.SECONDS)//每隔10秒重新执行任务
.build()
上面的代码实现的功能是每隔10秒重新执行任务,传入的时间最短不能少于10 秒钟。第一个参数则用于指定如果任务再次执行失败,下次重试的时间应该以什么样的形式延迟。第一个参数的可选值有两种,分别是LINEAR和EXPONENTIAL,前者代表下次重试时间以线性的方式延迟,后者代表下次重试时间以指数的方式延迟。
对后台任务的运行结果进行监听
我们需要调用getWorkInfoByIdLiveData()
方法得到LiveData对象,通过LiveData对象的observe()
方法来观察数据变化,实现监听。
WorkManager.getInstance()
.getWorkInfoByIdLiveData(request.id)
.observe(this, android.arch.lifecycle.Observer { workInfo ->
if (workInfo != null) {
if (workInfo.state == WorkInfo.State.SUCCEEDED) {
Log.d("MainActivity", "do work succeeded")
} else if (workInfo.state == WorkInfo.State.FAILED) {
Log.d("MainActivity", "do work failed")
}
}
})
WorkManager的特色功能——链式任务
val sync = ...
val compress = ...
val upload = ...
WorkManager.getInstance()
.beginWith(sync) //可添加多个任务
.then(compress)
.then(upload)
.enqueue()
在上述代码中,我们定义了3个独立的后台任务。beginWith()
方法用于开启一个链式任务,then()
方法连接不同任务。值得注意的是,要在一个任务执行完毕后才能执行下一个任务
总结
推荐处理的工作
- 立即执行:必须立即开始且很快就完成的任务,可以加急
- 长时间运行:运行时间可能较长(有可能超过 10 分钟)的任务。
- 可延期执行:延期开始并且可以定期运行的预定任务。
这就是 WorkManager API 的基础知识,相信你已经可以了解到WorkManager的使用。