当前位置:网站首页>WorkManager的学习二
WorkManager的学习二
2022-07-05 09:49:00 【Mr_Tony】
一、前言
Work
在运行期间有几种状态。在运行过程中, State
也随之改变。当任务开始是,状态是 ENQUEUED
。运行时转变为RUNNING
,运行结束时会变成 SUCCEEDED
、FAILED
。如果是重试的话,状态会重新回到ENQUEUED
。如果取消工作,状态就会变成 CANCELLED
。
SUCCEEDED
、FAILED
和 CANCELLED
均表示此工作的终止状态。如果您的工作处于上述任何状态,WorkInfo.State.isFinished()
都将返回 true。
以下是任务执行的流程图
上面是一个一次性任务的执行流程。如果是定时任务,那么就不会有SUCCEEDED
、FAILED
状态。以下是定时任务的流程图。
二、唯一工作
一般来说启动工作可以使用以下方式
WorkManager
.getInstance(this)
.enqueue(uploadWorkRequest)
不过如果我们无意中写了两次该代码,那么任务就会执行两次(虽说这个是不应该出现的)。为了避免这个问题,官方对一次性任务和定时任务分别提供了保证其唯一执行的方式。
这两种方法都接受 3 个参数:
- uniqueWorkName - 用于唯一标识工作请求的
String
。 - existingWorkPolicy - 此
enum
可告知 WorkManager:如果已有使用该名称且尚未完成的唯一工作链,应执行什么操作。如需了解详情,请参阅冲突解决政策。 - work - 要调度的
WorkRequest
。
参考代码如下:
val sendLogsWorkRequest =
PeriodicWorkRequestBuilder<SendLogsWorker>(24, TimeUnit.HOURS)
.setConstraints(Constraints.Builder()
.setRequiresCharging(true)
.build()
)
.build()
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
"sendLogs",
ExistingPeriodicWorkPolicy.KEEP,
sendLogsWorkRequest
)
三、冲突策略
以下参考官网
调度唯一工作时,您必须告知 WorkManager 在发生冲突时要执行的操作。您可以通过在将工作加入队列时传递一个枚举来实现此目的。
对于一次性工作,您需要提供一个
ExistingWorkPolicy
,它支持用于处理冲突的 4 个选项。
REPLACE
:用新工作替换现有工作。此选项将取消现有工作。KEEP
:保留现有工作,并忽略新工作。APPEND
:将新工作附加到现有工作的末尾。此政策将导致您的新工作链接到现有工作,在现有工作完成后运行。现有工作将成为新工作的先决条件。如果现有工作变为
CANCELLED
或FAILED
状态,新工作也会变为CANCELLED
或FAILED
。如果您希望无论现有工作的状态如何都运行新工作,请改用APPEND_OR_REPLACE
。
APPEND_OR_REPLACE
函数类似于APPEND
,不过它并不依赖于先决条件工作状态。即使现有工作变为CANCELLED
或FAILED
状态,新工作仍会运行。对于定期工作,您需要提供一个
ExistingPeriodicWorkPolicy
,它支持REPLACE
和KEEP
这两个选项。这些选项的功能与其对应的 ExistingWorkPolicy 功能相同。
四、观察工作的状态
当工作启动后,可以通过以下方式获取相应的工作信息。
// by id
workManager.getWorkInfoById(syncWorker.id) // ListenableFuture<WorkInfo>
// by name
workManager.getWorkInfosForUniqueWork("sync") // ListenableFuture<List<WorkInfo>>
// by tag
workManager.getWorkInfosByTag("syncTag") // ListenableFuture<List<WorkInfo>>
上面三种获取的方式对应的赋值方式如下:
// by id
val uploadWorkRequest: OneTimeWorkRequest = OneTimeWorkRequest.from(WorkTest::class.java)//简单方式
val workerId = uploadWorkRequest.id
//by name
WorkManager
.getInstance(this)
.enqueueUniqueWork("workName",
ExistingWorkPolicy.KEEP,
uploadWorkRequest)
//by tag
val uploadWorkRequest: WorkRequest = //复杂的构建器方式
OneTimeWorkRequestBuilder<WorkTest>()
.addTag("first")
.build()
该查询会返回
WorkInfo
对象的ListenableFuture
,该值包含工作的id
、其标记、其当前的State
以及通过Result.success(outputData)
设置的任何输出数据。利用每个方法的
LiveData
变种,您可以通过注册监听器来观察WorkInfo
的变化(需要注意的是调用的函数名字是getWorkInfoByIdLiveData而不是getWorkInfoById())。例如,如果您想要在某项工作成功完成后向用户显示消息,您可以进行如下设置:workManager.getWorkInfoByIdLiveData(syncWorker.id) .observe(viewLifecycleOwner) { workInfo -> if(workInfo?.state == WorkInfo.State.SUCCEEDED) { Snackbar.make(requireView(), R.string.work_completed, Snackbar.LENGTH_SHORT) .show() } }
五、复杂的查询
WorkManager 2.4.0 及更高版本支持使用
WorkQuery
对象对已加入队列的作业进行复杂查询。WorkQuery 支持按工作的标记、状态和唯一工作名称的组合进行查询。以下示例说明了如何查找带有“syncTag”标记、处于
FAILED
或CANCELLED
状态,且唯一工作名称为“preProcess”或“sync”的所有工作。val workQuery = WorkQuery.Builder .fromTags(listOf("syncTag")) .addStates(listOf(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED)) .addUniqueWorkNames(listOf("preProcess", "sync")) .build() val workInfos: ListenableFuture<List<WorkInfo>> = workManager.getWorkInfos(workQuery)
WorkQuery
中的每个组件(标记、状态或名称)与其他组件都是AND
逻辑关系。组件中的每个值都是OR
逻辑关系。例如:(name1 OR name2 OR ...) AND (tag1 OR tag2 OR ...) AND (state1 OR state2 OR ...)
。
WorkQuery
也适用于等效的 LiveData 方法getWorkInfosLiveData()
。
六、取消和停止工作
任务有时候需要取消,可以使用以下方式
// by id
workManager.cancelWorkById(syncWorker.id)
// by name
workManager.cancelUniqueWork("sync")
// by tag
workManager.cancelAllWorkByTag("syncTag")
WorkManager 会在后台检查工作的
State
。如果工作已经完成,系统不会执行任何操作。否则,工作的状态会更改为CANCELLED
,之后就不会运行这个工作。任何依赖于此工作的WorkRequest
作业也将变为CANCELLED
。目前,
RUNNING
可收到对ListenableWorker.onStopped()
的调用。如需执行任何清理操作,请替换此方法。如需了解详情,请参阅停止正在运行的工作器。
所以任务停止后,可以在重写的onStopped()
函数中处理收尾工作。也可以通过 ListenableWorker.isStopped()
来见擦汗任务是否停止,示例如下:
class WorkTest(val appContext: Context, workerParams: WorkerParameters): Worker(appContext, workerParams) {
override fun doWork(): Result {
if(isStopped){
return Result.success()
}
return Result.success()
}
}
七、参考链接
边栏推荐
- Have you learned to make money in Dingding, enterprise micro and Feishu?
- Fluent development: setting method of left and right alignment of child controls in row
- leetcode:1200. 最小绝对差
- ArcGIS Pro creating features
- Jupiter notebook shortcut key
- Wechat applet - simple diet recommendation (4)
- 剪掉ImageNet 20%数据量,模型性能不下降!Meta斯坦福等提出新方法,用知识蒸馏给数据集瘦身...
- 【 conseils 】 obtenir les valeurs des axes X et y de la fonction cdfplot dans MATLAB
- 【C语言】动态内存开辟的使用『malloc』
- MySQL数字类型学习笔记
猜你喜欢
Usage differences between isempty and isblank
Wechat applet - simple diet recommendation (4)
@SerializedName注解使用
双容水箱液位模糊PID控制系统设计与仿真(Matlab/Simulink)
pytorch输出tensor张量时有省略号的解决方案(将tensor完整输出)
ConstraintLayout的流式布局Flow
StaticLayout的使用详解
ArcGIS Pro 创建要素
[tips] get the x-axis and y-axis values of cdfplot function in MATLAB
Meitu lost 300 million yuan in currency speculation for half a year. Huawei was exposed to expand its enrollment in Russia. Alphago's peers have made another breakthrough in chess. Today, more big new
随机推荐
How to get the STW (pause) time of GC (garbage collector)?
官网给的这个依赖是不是应该为flink-sql-connector-mysql-cdc啊,加了依赖调
@SerializedName注解使用
AtCoder Beginner Contest 258「ABCDEFG」
Is it really reliable for AI to make complex decisions for enterprises? Participate in the live broadcast, Dr. Stanford to share his choice | qubit · viewpoint
基于单片机步进电机控制器设计(正转反转指示灯挡位)
双容水箱液位模糊PID控制系统设计与仿真(Matlab/Simulink)
Single chip microcomputer principle and Interface Technology (esp8266/esp32) machine human draft
横向滚动的RecycleView一屏显示五个半,低于五个平均分布
pytorch输出tensor张量时有省略号的解决方案(将tensor完整输出)
Optimize database queries using the cursor object of SQLite
Design and Simulation of fuzzy PID control system for liquid level of double tank (matlab/simulink)
天龙八部TLBB系列 - 关于包裹掉落的物品
QT timer realizes dynamic display of pictures
学习笔记5--高精地图解决方案
> Could not create task ‘:app:MyTest. main()‘. > SourceSet with name ‘main‘ not found. Problem repair
[论文阅读] CKAN: Collaborative Knowledge-aware Atentive Network for Recommender Systems
ConstraintLayout的流式布局Flow
Openes version query
剪掉ImageNet 20%数据量,模型性能不下降!Meta斯坦福等提出新方法,用知识蒸馏给数据集瘦身...