App 有时可能需要定期运行某些工作。例如,可能要定期备份数据、上传信息到服务器,定期获取新的内容等等。
在 app 运行期间,我们使用 Handler 也可以完成定期的功能。在这里我们介绍 WorkManager 使用定时任务的方法。
前面我们介绍了 WorkManager 的使用方法,约束和延迟等。本文介绍 WorkManager 的定时任务。如何创建定时任务,查看任务状态,取消任务。
本文使用 kotlin
注意:可以定义的最短重复间隔是 15 分钟(与 JobScheduler API 相同)。
gradle
kotlin 使用 PeriodicWorkRequestBuilder 时候报错误提示
Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6.
Please specify proper '-jvm-target' option
根据提示,在 app 的 gradle 配置添加 kotlinOptions
的 jvmTarget
android {
// 其他配置...
kotlinOptions {
jvmTarget = "1.8"
}
}
创建定时任务
创建定时任务,用到 PeriodicWorkRequestBuilder,传入定时的参数,build()
得到任务实例。
交给 WorkManager 的 enqueue
方法即可。
val r1 = PeriodicWorkRequestBuilder<UploadWorker2>(15, TimeUnit.MINUTES)
.addTag("r1").build()
WorkManager.getInstance(applicationContext).enqueue(r1)
上面的代码,enqueue
后会立刻执行一次任务。
多次创建任务,可以得到多个定时任务。
注意:可以定义的最短重复间隔是 15 分钟(与 JobScheduler API 相同)。
单一任务
如果不想要重复的定时任务,需要用 WorkManager 的 enqueueUniquePeriodicWork
方法。
val r1 = PeriodicWorkRequestBuilder<UploadWorker2>(15, TimeUnit.MINUTES)
.addTag("r2").build()
WorkManager.getInstance(applicationContext)
.enqueueUniquePeriodicWork(
"单独的定时任务r2",
ExistingPeriodicWorkPolicy.KEEP,
r1)
用 PeriodicWorkRequestBuilder 创建出任务后。
调用 enqueueUniquePeriodicWork
,此方法需要 3 个参数:
uniqueWorkName
唯一的任务名字ExistingPeriodicWorkPolicy
发现任务重复时的处理方法REPLACE
把旧的任务停止并删除,然后插入新的任务KEEP
保留原来的任务,不新增任务
PeriodicWorkRequest
任务对象
enqueueUniquePeriodicWork
方法能保证 1 个名字同时只有一个定时任务(PeriodicWorkRequest)。
如果是同样的名字(uniqueWorkName),插入任务时可能会替换旧任务(REPLACE),或者不影响旧任务(KEEP)。
查看任务
在这里我们用 getWorkInfosByTag
来查询任务
val status = WorkManager.getInstance(applicationContext).getWorkInfosByTag("r1")
val workInfoList: List<WorkInfo> = status.get()
for (w in workInfoList) {
Log.d("rustfisher.com", " $w")
}
查询结果的例子
WorkInfo{mId='83d7d512-8a5d-4613-acbb-e73ee2855212', mState=ENQUEUED, mOutputData=Data {}, mTags=[com.rustfisher.tutorial2020.workmanaer.WorkManagerAct$UploadWorker2, r1], mProgress=Data {}}
取消任务
我们有多种取消任务的方法。
取消所有任务
cancelAllWork()
,取消所有任务
WorkManager.getInstance(applicationContext).cancelAllWork()
取消单独的任务
cancelUniqueWork(uniqueWorkName: String)
,取消单独的任务,传入 uniqueWorkName
WorkManager.getInstance(applicationContext).cancelUniqueWork("单独的定时任务r2")
取消传入 tag 的所有任务
cancelAllWorkByTag(tag)
,取消传入 tag 的所有任务
WorkManager.getInstance(applicationContext).cancelAllWorkByTag("r1")
取消特定 UUID 的任务
cancelWorkById(UUID)
,取消特定 UUID 的任务
WorkManager.getInstance(applicationContext).cancelWorkById(UUID)
取消任务后,再去查询任务状态,会发现 mState=CANCELLED
WorkInfo{mId='7c9e0deb-5267-4ade-8b95-c695e57f274c', mState=CANCELLED, mOutputData=Data {}, mTags=[r2, com.rustfisher.tutorial2020.workmanaer.WorkManagerAct$UploadWorker2], mProgress=Data {}}
参考
- WorkManager 使用入门 https://an.rustfisher.com/android/jetpack/workManager/use1/
- WorkManager 工作约束,延迟与查询工作 https://an.rustfisher.com/android/jetpack/workManager/use2/
- 定期工作 https://developer.android.com/topic/libraries/architecture/workmanager/how-to/define-work#schedule_periodic_work
- 观察工作 https://developer.android.com/topic/libraries/architecture/workmanager/how-to/managing-work#observing
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于