持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
前言
上一篇我们了解了关于workmanager基本的信息,这一篇我们着重了解一下Worker。
概览
Worker是在WorkManager提供的后台线程上同步执行工作的类。继承于ListenableWorker, Worker类在运行时是通过WorkManager实例化,doWork()方法在预先指定的后台线程上调用,这个方法用于同步处理你的工作,一旦该方法返回,工作就被认为已经完成并将被销毁。
基本使用
// work类
class MyWorker : Worker() {
override fun doWork(): Worker.WorkerResult {
//这里执行work工作
...
// 这里提供三个返回
// a. WorkerResult.SUCCESS 工作执行成功
// b. WorkerResult.FAILURE 工作执行失败
// c. WorkerResult.RETRY 工作执行重试
return Worker.WorkerResult.SUCCESS
}
}
API使用
getInputData
在Worker中获取外部WorkRequest由setInputDataapi所传递的数据,传递的数据类型只支持基本数据类型及其数组以及序列化数据,和Bundle传递的数据类似。
// work类
class MyWorker : Worker() {
override fun doWork(): Worker.WorkerResult {
// 获取数据
val inputData = inputData.getString("INPUT_DATA")
return Worker.WorkerResult.SUCCESS
}
}
setProgressAsync
在Worker中可以通过setProgressAsync()来设置进度和数据。setProgressAsync()是一个异步操作方法,会调用ProgressUpdater的updateProgress()操作数据库。只有WorkInfo的状态为RUNNING时才可以获取到setProgressAsync()设置的进度数据。
// work类
class MyWorker : Worker() {
override fun doWork(): Worker.WorkerResult {
// 模拟1000后进度更新
setProgressAsync(workDataOf(Pair("key", 0)))
Thread.sleep(1000)
setProgressAsync(workDataOf(Pair("key", 100)))
return Worker.WorkerResult.SUCCESS
}
}
// 观察进度
WorkManager.getInstance(this).getWorkInfoByIdLiveData(myWorkId).observe(lifecycleOwner, workStatus -> {
if (null != workStatus && workStatus.state == WorkInfo.State.RUNNING) {
// 获取进度数据
val progress = workStatus.progress
val value = progress.getString("key")
}
})
setForegroundAsync
在Worker中可以通过setForegroundAsync()来指定当前工作需要长时间运行,请求加入前台任务,尽可能的让系统保证进程的活动状态。需要注意的是调用setForegroundAsync必须在ListenableWorker返回ListenableWorker. result信号完成之前完成。 在底层,WorkManager管理并运行一个前台服务来代表你执行这个WorkRequest,并在ForegroundInfo中显示提供的通知。
// work类
class MyWorker : Worker() {
override fun doWork(): Worker.WorkerResult {
// 设置前台任务
setForegroundAsync(createForegroundInfo())
// 调用`setForegroundAsync`必须在`ListenableWorker`返回`ListenableWorker. result`信号完成之前完成
return Worker.WorkerResult.SUCCESS
}
private fun createForegroundInfo(): ForegroundInfo {
val notificationCompat =
NotificationCompat.Builder(applicationContext, "channelId").setContentTitle("标题")
.setSmallIcon(R.drawable.icon_odd_close)
.setOngoing(true)//是否为持续通知
.build()
return ForegroundInfo(123,notificationCompat)
}
}