Android WorkManager工作約束,延遲與查詢工作

WorkManager工作約束,延遲與查詢工作

本文可能會混用“工作”與“任務”這兩個詞。
本文例子使用Kotlin

準備一個工作類(任務)UploadWorker2

class UploadWorker2(context: Context, params: WorkerParameters) : Worker(context, params) {
    override fun doWork(): Result {
        Log.d(TAG, "模擬執行任務2 ${Thread.currentThread()}")
        return Result.success()
    }
}

工作約束

約束可讓工作延遲到滿足最佳條件時運行。下面的約束適用於 WorkManager

名稱 說明
NetworkType 約束運行工作所需的網絡類型。例如 Wi-Fi (UNMETERED)。
BatteryNotLow 若爲 true,那麼當設備處於“電量不足模式”時,工作不會運行。
RequiresCharging 若爲 true,那麼工作只能在設備充電時運行。
DeviceIdle 若爲 true,則設備必須處於空閒狀態才能運行工作。如果考慮到其他應用的性能,建議用這個約束。
StorageNotLow 若爲 true,那麼當設備上的存儲空間不足時,工作不會運行。

可用Constraints.Builder()來創建工作約束。然後將Constraints實例分配給WorkRequest.Builder()
也就是說,工作約束是針對工作WorkRequest的。

下面這個工作約束,只有1個要求,在設備使用計費流量是執行任務。

val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.METERED)
        .build()
val d1 = OneTimeWorkRequest.Builder(UploadWorker2::class.java)
        .setConstraints(constraints)
        .addTag("約束").build()
mIdList.add(d1.id) // 登記任務id,可去掉
WorkManager.getInstance(applicationContext).enqueue(d1)

真機測試中,如果一開始手機用着wifi,那麼任務不會執行。而關掉wifi,打開流量開關,就會執行任務。
這就是滿足最佳條件時運行。

NetworkType說明

androidx.work.NetworkType是一個枚舉類。目前有

枚舉 說明
NOT_REQUIRED 這個工作不需要網絡
CONNECTED 這個工作需要有網絡連接
UNMETERED 需要Wi-Fi
NOT_ROAMING 非漫遊網絡
METERED 需要按流量計費的網絡

延遲工作

如果工作沒有約束,或者當工作加入隊列時所有約束都得到了滿足,那麼系統可能會選擇立即運行該工作。
如果不希望工作立即運行,可以給工作設定一個延遲時間。

下面這個工作是要延遲3秒鐘。

val d1 = OneTimeWorkRequest.Builder(UploadWorker2::class.java)
        .addTag("延遲1")
        .setInitialDelay(3, TimeUnit.SECONDS)
        .build()
WorkManager.getInstance(applicationContext).enqueue(d1)

enqueue任務後,查一下任務狀態。工作從ENQUEUED狀態,執行完畢後變成了SUCCEEDED

WorkInfo{mId='2794b4dd-7c02-4fd0-9851-8798a0da3bb2', mState=ENQUEUED, mOutputData=Data {}, mTags=[com.rustfisher.tutorial2020.workmanaer.WorkManagerAct$UploadWorker2, 延遲1], mProgress=Data {}}

WorkInfo{mId='2794b4dd-7c02-4fd0-9851-8798a0da3bb2', mState=SUCCEEDED, mOutputData=Data {}, mTags=[com.rustfisher.tutorial2020.workmanaer.WorkManagerAct$UploadWorker2, 延遲1], mProgress=Data {}}

查詢工作

使用UUID查詢

新建工作的時候,系統會分配一個UUID。我們可以記錄UUID到mIdList裏。通過UUID可以查詢到工作當前的狀態。

val mgr = WorkManager.getInstance(applicationContext)
for (id in mIdList) {
    val cur = mgr.getWorkInfoById(id)
    Log.d(TAG, "查詢任務 ${cur.get()}")
}

一個工作狀態的例子,狀態是ENQUEUED

WorkInfo{mId='16cc292d-f140-488f-9ab5-a0d22b95d128', mState=ENQUEUED, mOutputData=Data {}, mTags=[com.rustfisher.tutorial2020.workmanaer.WorkManagerAct$UploadWorker, r1], mProgress=Data {}}

使用tag查詢

前面我們給工作打上tag。可以用WorkManagergetWorkInfosByTag()方法把指定tag的工作查出來。

val mgr = WorkManager.getInstance(applicationContext)

for (w in mgr.getWorkInfosByTag("約束1").get()) {
    Log.d(TAG, "$w")
}

工作狀態的例子,下面這個工作UploadWorker狀態是SUCCEEDED,tag裏有約束1

WorkInfo{mId='fed1974c-77e5-46ba-8b38-f6c01d68fe4c', mState=SUCCEEDED, mOutputData=Data {}, mTags=[com.rustfisher.tutorial2020.workmanaer.WorkManagerAct$UploadWorker, 約束1], mProgress=Data {}}

需要注意的是,工作的狀態是存儲起來的。即使重啓app或者手機,都可以查到這個工作的狀態。
假設查詢tag是約束1,我們能得到之前創建的含有這個約束1標籤的工作。

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章