Android WorkManager 定時任務

AnRFDev發表於2021-08-30

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配置新增kotlinOptionsjvmTarget

android {
    // 其他配置...

    kotlinOptions {
        jvmTarget = "1.8"
    }
}

建立定時任務

建立定時任務,用到PeriodicWorkRequestBuilder,傳入定時的引數,build()得到任務例項。
交給WorkManagerenqueue方法即可。

val r1 = PeriodicWorkRequestBuilder<UploadWorker2>(15, TimeUnit.MINUTES)
        .addTag("r1").build()
WorkManager.getInstance(applicationContext).enqueue(r1)

上面的程式碼,enqueue後會立刻執行一次任務。
多次建立任務,可以得到多個定時任務。

注意:可以定義的最短重複間隔是 15 分鐘(與 JobScheduler API 相同)。

單一任務

如果不想要重複的定時任務,需要用WorkManagerenqueueUniquePeriodicWork方法。

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 {}}

參考

相關文章