WorkManager目前还在Alpha阶段,还存在一些问题。不过等后续Release后,又是开发的一大助力。
而它的主要作用则是管理在后台工作的任务,即使APP没有启动,它也能保证任务可以被执行。
WorkManager会在System_Server的进程中保存任务,当某些时机到了之后,会通过Binder回调到应用进程中执行该任务。
在5.0以上的版本WorkManager会通过JobScheduler或者Firebase的JobDispatcher来实现,而在5.0以下的版本,则会通过AlarmManager来实现
它有以下好处:
但是WorkManager仍然无法代替线程池、AsyncTask,例如以下的例子都可以使用WorkManager:上传日志,实现图片的滤镜并且保存图片,定期从网络同步本地数据。
1.0.0-alpha13
。dependencies {
implementation "android.arch.work:work-runtime-ktx:$versions.work"
}
doWork
函数,返回任务执行的结果,并且在任务中可以携带数据返回结果。class TestWorker(ctx: Context, params: WorkerParameters) : Worker(ctx, params) {
private val TAG by lazy { TestWorker::class.java.simpleName }
private val KEY_EXCEPTION by lazy { "KEY_EXCEPTION" }
private val KEY_SUCCESS by lazy { "KEY_SUCCESS" }
override fun doWork(): Result {
return try {
Log.e(TAG, "Worker Do Work")
val successData = Data.Builder().putString(KEY_SUCCESS, "Success").build()
Result.success(successData)
} catch (exception: Exception) {
val exceptionData = Data.Builder().putString(KEY_EXCEPTION, "Exception :${exception.message}").build()
Result.failure(exceptionData)
}
}
}
OneTimeWorkRequest
,并且携带了输入的参数setInputData
,创建完后,就可以将它插入到WorkManager的队列中等待执行。val inputData = Data.Builder().putString("KEY_INPUT", "input data").build()
val workRequest = OneTimeWorkRequest.Builder(TestWorker::class.java).setInputData(inputData).build()
WorkManager.getInstance().enqueue(workRequest)
通过
PeriodicWorkRequest
创建的任务,是会定期执行的,需要传入定期的时间即可
当某些任务具有依赖关系时候(如A依赖B完成的结果,B又依赖C完成的结果),则需要使用链式任务。
链式任务
可以通过WorkManager.beginWith
来开始执行任务,并且通过then
来将后续的任务链接上。并且可以将前一个任务的输出作为后一个任务的输入。
val workA = OneTimeWorkRequest.Builder(TestWorker::class.java).build()
val workB = OneTimeWorkRequest.Builder(BlurWorker::class.java).build()
val workC = OneTimeWorkRequest.Builder(CleanupWorker::class.java).build()
WorkManager.getInstance().beginWith(workA).then(workB).then(workC).enqueue()
如果只允许单独的任务存在的话,则需要通过beginUniqueWork
来开启任务。当存在重复的任务时,会采用传入的ExistingWorkPolicy
来对已存在的任务进行策略处理。
WorkManager.getInstance().beginUniqueWork("workName",ExistingWorkPolicy.REPLACE,workA).enqueue()
在任务执行的过程中,可以通过LiveData
来监听任务的状态,所有的任务都具有这几种状态:
addTag
设置任务的Tagval workRequest = OneTimeWorkRequest.Builder(TestWorker::class.java).addTag("workRequest").build()
WorkManager.getInstance().enqueue(workRequest)
1.0.0-alpha10
版本中,还可以通过WorkManager.getInstance().getStatusesByTagLiveData()
获取对应的Worker的Status。而1.0.0-alpha13
版本中,已经没有该函数了,已经替换成getWorkInfosByTagLiveData
,而获取的也就是WorkInfo,也差不多。
val liveData = WorkManager.getInstance().getWorkInfosByTagLiveData("workRequest");
liveData.observe(this, Observer {
if (it[0].state.isFinished) {
// 任务已经完成
} else {
// 任务未完成
}
})
在WorkManager中也可以取消:
// 根据TAG取消所有任务
WorkManager.getInstance().cancelAllWorkByTag()
// 根据UniqueWorkName取消任务
WorkManager.getInstance().cancelUniqueWork()
// 根据uuid取消任务
WorkManager.getInstance().cancelWorkById()
当某个任务需要在某个条件时开始,可以在任务的Builder
中添加约束(Constraint)。
// 创建正在充电的约束
val constraints = Constraints.Builder()
.setRequiresCharging(true)
.build()
// 将约束添加到请求中
val save = OneTimeWorkRequestBuilder<BlurWorker>()
.setConstraints(constraints)
.addTag(TAG_OUTPUT)
.build()
continuation = continuation.then(save)
// 启动任务
continuation.enqueue()