上一篇说到,周期性延时任务,实际被非延时的周期任务给干扰了。这是因为,任务一直是添加到系统的,应用未启动的时候,不会有,但是当应用重新启动过后,如果条件满足,之前添加的周期性任务就会执行。
既然如此,是时候来学习下如何取消任务了。
取消任务
WorkManager
里共有四个取消任务接口:
1 |
|
- 第一个方法,需要Worker的id作为参数
- 第二个方法,需要Worker的tag标记作为参数
- (Work chain??还不懂,先不管)
- 第四个方法,不用参数,取消所有任务
取消所有
先来个简单的,取消所有任务(点击启动后,迅速点击取消所有):
1 |
|
执行结果:
1 |
|
日志中看到,虽然调用了cancel,但是当前任务的“ended”还是打出来了。这是因为,已经执行的任务将继续执行,不受cancel影响,cancel的目标是后续的周期任务。
同时,因为调用了cancelAllWork
,之前测试添加的任务项也一并消除了。
通过id
Worker的id从哪儿来呢?构造的时候任务时候,只生成了一个WorkerRequest对象,果然它有一个获取id的方法:
1 |
|
同样点击启动后,迅速取消:
1 |
|
执行结果:
1 |
|
通过tag
通过tag取消任务,与通过id类似,不同之处在于:id是reqeuest构造的时候,自动生成的;但tag则需要自行添加
1 |
|
取消任务:
1 |
|
执行结果:
1 |
|
任务信息监听
有没有发现,前面取消任务的各种操作,都只是日志显示调用了cancel,并不能证明真的成功cancel任务了。除非真的坐等15分钟,看有没有执行下一次任务……(hmmmm…当然,本人写这些话的时候,确实等了15分钟+,也证明确实cancel成功了)。
所以问题来了,有没有办法监听任务的实际状态呢?当然有啊!秘密就在WorkManager
里:
1 |
|
通过id,可以获取一个LiveData,数据类型是WorkInfo
,来看看它是个什么货
1 |
|
WorkInfo
包含了request的id信息,还有一个WorkInfo.State
枚举,用于表示request的生命周期。
既然是LiveData,自然就可以observe监听了:
1 |
|
启动周期任务 -> 等一次执行完成 -> 取消任务,来看看执行结果:
1 |
|
可以看到,相应的WorkRequest状态的变化为:RUNNING -> ENQUEUED -> CANCELLED
如果在执行完就cancel呢:
1 |
|
状态的变化为:RUNNING -> CANCELLED
因为任务取消,当然不用再次添加到下一个周期了,所以没有ENQUEUED。即便当次任务执行完成,也并没有出现SUCCEEDED状态,因为周期任务是不可能达到SUCCEEDED状态的。顺便来对比下OneTimeRequest的执行状态变化。
1 |
|
结果:
1 |
|
如前所料,状态变化为:RUNNING -> SUCCEEDED
实验
前面有说到:应用启动时,如有历史添加的Worker,将重新添加回来,满足条件就会继续执行。下面验证一下。
首先,在应用启动时候就添加好监听,同时任务项里也打印出id。
1 |
|
任务启动时,存好id
1 |
|
-
启动定时任务:
1
2
3
4
52021-01-13 17:20:07.081 5586-5586/com.jacee.examples.workmanager D/JTest: enqueue periodic on 2 1610529607081 2021-01-13 17:20:07.119 5586-5630/com.jacee.examples.workmanager D/JTest: doWork on 6872 started - 1610529607119 -> 5c52487f-e0fd-4cad-ad8d-7cd2be6b2995 2021-01-13 17:20:07.128 5586-5586/com.jacee.examples.workmanager D/JTest: periodic: 5c52487f-e0fd-4cad-ad8d-7cd2be6b2995: RUNNING 2021-01-13 17:20:10.124 5586-5630/com.jacee.examples.workmanager D/JTest: doWork on 6872 ended - 1610529610124 2021-01-13 17:20:10.203 5586-5586/com.jacee.examples.workmanager D/JTest: periodic: 5c52487f-e0fd-4cad-ad8d-7cd2be6b2995: ENQUEUED
- 杀掉应用,等待15分钟以上(15分是该任务的周期)
- 再次启动应用,观察是否有历史任务继续执行
结果:
1 |
|
可以看到,确实是id为5c52487f-e0fd-4cad-ad8d-7cd2be6b2995的任务,又执行了。因为已经隔了20分钟,所以任务是立即执行的,而且周期任务将ENQUEUED
,继续进行。
小结
至此,WorkManager的任务添加、取消以及任务状态的监听,算是基本介绍完了,当然有些细节是没有深入的。
前面谈取消任务的时候,有一个方法cancelUniqueWork
有涉及到chain work的概念,是什么呢?下回再来学习吧