1、介绍文章(国内可访问)https://zhuanlan.zhihu.com/p/78599394
implementation("androidx.work:work-runtime-ktx:2.5.0")
先看准备代码,两个模拟任务类,此处的返回结果有三种
Result.success是将任务流执行到最后
Result.fails会将任务流断开,不再执行之后的任务,类似rx流异常
Result.retry会将当前任务重复执行,有默认30秒的间隔执行时间,重复执行策略可通过
可以任务属性上设置
.setBackoffCriteria(
BackoffPolicy.LINEAR,
OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
TimeUnit.MILLISECONDS)
最小重试时间为10秒
class LogManager(context: Context, private val workerParams: WorkerParameters) : Worker(context, workerParams) {
override fun doWork(): Result {
val value = workerParams.inputData.getString("key")
for (i in 0..10) {
Thread.sleep(800)
HLog.d("-->work.log:$i$value")
HToast.showToastSuccess("-->work.log:$i$value")
}
val resultData = Data.Builder()
.putString("resultKey","log->FINIGHS")
.build()
return Result.success(resultData)
}
}
class UpdateManager(context: Context, private val workerParams: WorkerParameters) : Worker(context, workerParams) {
override fun doWork(): Result {
val value = workerParams.inputData.getString("key")
for (i in 0..15) {
Thread.sleep(900)
HLog.d("-->work.upLoad:$i$value")
HToast.showToastSuccess("-->work.upLoad:$i$value")
}
val resultData = Data.Builder()
.putString("resultKey","upLoad-FINIGHS")
.build()
return Result.success(resultData)
}
}
任务触发条件设置
val constraints: Constraints = Constraints.Builder()
.setRequiresCharging(true)//设置是否充电的条件,默认false
.setRequiresDeviceIdle(false)// 设置手机是否空闲的条件,默认false
.setRequiredNetworkType(NetworkType.CONNECTED)//设置需要的网络条件,默认NETWORK_TYPE_NONE
.setRequiresBatteryNotLow(true)
.build()
创建一次性任务,使用Data传递work中需要的参数
//且数据最大不能超过10kb
val logData = Data.Builder()
.putString("key", "logData")
.build()
val logWorkRequest = OneTimeWorkRequest.Builder(LogManager::class.java)
.addTag("LogTask")
.setInputData(logData)
.setBackoffCriteria(
BackoffPolicy.LINEAR,
OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
TimeUnit.MILLISECONDS)//设置重试策略
.setConstraints(constraints)
.build()
也可以创建循环任务,间隔时间15分钟以上
//周期性任务的间隔时间不能小于15分钟。
val logWorkRequest1 = PeriodicWorkRequest.Builder(LogManager::class.java, 15, TimeUnit.MINUTES)
.addTag("LogTask")
.setInputData(logData)
.setConstraints(constraints)
.build()
再写一个任务,以便后面进行多种类型调试
val updateData = Data.Builder()
.putString("key", "updateData")
.build()
val updateWorkRequest = OneTimeWorkRequest.Builder(UpdateManager::class.java)
.addTag("UpdateTask")
.setInputData(updateData)
.setConstraints(constraints)
.build()
前置条件见以上
一、模拟一个循环任务
//定时执行相关任务
WorkManager.getInstance(this)
.enqueue(logWorkRequest1)
二、执行单个任务
//单个任务执行
WorkManager.getInstance(this)
.enqueue(updateWorkRequest)
三、串行执行多个任务
//串行执行
WorkManager.getInstance(this)
.beginWith(logWorkRequest)
.then(updateWorkRequest)
.enqueue()
四、多任务合并执行,有点类型RX的zip等操作符,其中logWork与updateWork执行顺序不受控制,与上面的then有所区别
//多任务合并执行
val taskList: MutableList<WorkContinuation> = ArrayList()
val logWork = WorkManager.getInstance(this).beginWith(logWorkRequest)
val updateWork = WorkManager.getInstance(this).beginWith(updateWorkRequest)
taskList.add(logWork)
taskList.add(updateWork)
WorkContinuation.combine(taskList).enqueue()
五、另外需要获取任务的执行结果需要额外添加监听
WorkManager.getInstance(this)
.getWorkInfoByIdLiveData(logWorkRequest.id)
.observe(this, Observer { data ->
val result = data.outputData.getString("resultKey") ?: "-"
HLog.d("-->work.log:$result")
})
六、有一点取消任务不太好用
//只能取消未开始的任务
WorkManager.getInstance(this)
.cancelAllWorkByTag("LogTask")
最后:测试后发现在某些手机上当一个任务正在执行将app进行杀死,重新启动app,未执行完的任务会重新开始执行