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