WorkManager使用

注意: WorkManager 需要 compileSdk 版本 28 或更高版本
 

1. 添加maven倉庫依賴--> build.gradle(project)

    buildscript -->
        respositories --> 加入: maven { url "https://jitpack.io" }

    allprojects -->
        respositories --> 加入: maven { url "https://jitpack.io" }

2. 添加dependience依賴--> build.gradle(app)

    --java
    implementation "android.arch.work:work-runtime:1.0.1"

    --java ---> AndroidX:
    implementation "androidx.work:work-runtime:2.2.0"

    //workManager支持RxJava2
    implementation "androidx.work:work-rxjava2:2.3.4"

    --kotlin:
    implementation "androidx.work:work-runtime-ktx:2.3.4"

3. 常見擴展功能    

添加約束:例如指定工作應僅在設備空閒且接通電源時運行,
參考鏈接:https://developer.android.com/reference/androidx/work/Constraints.Builder
初始延遲:制定工作在經過最短的出式延遲後啓動
重試:如果需要讓workManager重新城市執行您的任務,可以從工作器返回Result.retry()
退避政策:定義了在後續重試的嘗試過程中,退避延遲時間以怎樣的方式增長,默認按照EXPONENTIAL延長
定義任務的輸入/輸出:當任務需要數據以輸入參數的形式傳入,或者將數據返回爲結果,輸入值和輸出值以鍵值對的形式存儲在Data對象中
標記工作:通過爲任意WorkRequest對象分配標記字符串,按邏輯對任務進行人族,這樣就可以對使用特定標記的所有任務執行操作

4. WorkManager的常見工作狀態

BLOCKED : 表示當前有尚未完成的前提性工作
ENQUEUED : 表示 工作能夠在滿足約束和時機條件後可立即執行
RUNNING : 表示工作器在活躍的執行
SUCCEEDED : 工作期返回成功的狀態,此時是一種終止的狀態,且只有OneTimeWorkRequest可以進入這種狀態
FAILED : 工作期返回失敗的狀態,此時是一種終止的狀態,所有依賴的工作也會被標記爲FAILED狀態,且只有OneTimeWorkRequest可以進入這種狀態
CANCELLED : 當明確取消尚未終止的WorkRequest時,它會進入CANCELLED狀態,所有依賴工作也會被標記爲CANCELLED狀態,且不會運行
5. 觀察/監聽工作的狀態
    
思路:將工作加入隊列後,您可以根據WorkManager檢查其狀態,狀態信息在WorkInfo對象中提供,包括工作的id、標籤、當前狀態和任何輸出數據

方式一:對於特定的WorkRequest,可以利用:
    WorkManager.getWorkInfoById(UUID)
    或
    WorkManager.getWorkInfoByIdLiveData(UUID) 來通過 WorkRequest id 檢索其 WorkInfo.

方式二:
    對於指定的標記,可以利用:
    WorkManager.getWorkInfosByTag(String)
    或
    WorkManager.getWorkInfosByTagLiveData(String) 檢索所有匹配的 WorkRequest 的 WorkInfo 對象

方式三:
    對於唯一工作名稱,可以利用:
    WorkManager.getWorkInfosForUniqueWork(String)
    或
    WorkManager.getWorkInfosForUniqueWorkLiveData(String) 檢索所有匹配的 WorkRequest 的WorkInfo 對象。

示例代碼:
WorkManager.getInstance(myContext).getWorkInfoByIdLiveData(uploadWorkRequest.getId()).observe(lifecycleOwner, new Observer<WorkInfo>() {
    @Override
    public void onChanged(@Nullable WorkInfo workInfo) {
        if (workInfo != null && workInfo.state == WorkInfo.State.SUCCEEDED) {
            displayMessage("Work finished!")
        }
    }
});

 

6. 監聽WorkManager的任務進度

    通過獲取WorkInfo對象的實例,此對象後一個返回的Data的新getProgress()方法獲取進度
    在工作任務初始化的時候,通過setProgressAsync(new Data.Builder().putInt(PROGRESS, 0).build()); 將講進度置爲0
    在工作任完成的時候,通過setProgressAsync(new Data.Builder().putInt(PROGRESS,100).build()); 將講進度置爲100

    觀察進度,代碼示例:
        WorkManager.getInstance(getApplicationContext())
             // requestId is the WorkRequest id
             .getWorkInfoByIdLiveData(requestId)
             .observe(lifecycleOwner, new Observer<WorkInfo>() {
                     @Override
                     public void onChanged(@Nullable WorkInfo workInfo) {
                         if (workInfo != null) {
                             Data progress = workInfo.getProgress();
                             int value = progress.getInt(PROGRESS, 0)
                             // Do something with progress
                     }
              }
        });

 

7. 創建工作鏈,鏈接work任務

可以使用WorkManager創建工作鏈併爲其排隊,工作鏈用於指定多個關聯任務並定義這些任務的運行順序.
    思路:
        使用 WorkManager.beginWith(OneTimeWorkRequest) 或 WorkManager.beginWith(List<OneTimeWorkRequest>),這會返回 WorkContinuation 實例;
        通過 WorkContinuation 使用 WorkContinuation.then(OneTimeWorkRequest) 或 WorkContinuation.then(List<OneTimeWorkRequest>) 來添加從屬 OneTimeWorkRequest。
        每次調用 WorkContinuation.then(...) 都會返回一個新的 WorkContinuation 實例。如果添加了 OneTimeWorkRequest 的 List,這些請求可能會並行運行。
        最後,您可以使用 WorkContinuation.enqueue() 方法爲 WorkContinuation 鏈排隊

    示例代碼:

            OneTimeWorkRequest compress =
                                new OneTimeWorkRequest.Builder(CompressWorker.class)
                                    .setInputMerger(ArrayCreatingInputMerger.class)
                                    .setConstraints(constraints)
                                    .build();


            WorkManager.getInstance(myContext)
                // Candidates to run in parallel
                .beginWith(Arrays.asList(filter1, filter2, filter3))
                .then(compress)
                .then(upload)
                // Don't forget to enqueue()
                .enqueue();

    代碼解析:
        OverwritingInputMerger: 會嘗試將所有輸入中的所有鍵添加到輸出中。如果發生衝突,它會覆蓋先前設置的鍵。
        ArrayCreatingInputMerger: 會嘗試合併輸入,並在必要時創建數組.

        父級別任務的輸出將作爲輸入傳遞給子級
        父級別的請求任務都成功完成時,即返回Result.success時,纔會被解除阻塞變爲ENQUEUED狀態.
        父級別請求任務返回失敗,則叢書的請求也都會被標記爲FAILED狀態
        父級別請求任務被取消,則叢書的請求也都會被標記爲CANCELLED狀態

 

8. 取消和停止工作

    如果不需要運行前加入隊列,則可以申請取消
    思路:使用其od並調用WorkManager.cancelWorkById(UUID) 來取消單個 WorkRequest:
    示例代碼:
            WorkManager.cancelWorkById(workRequest.getId());

 

9. 重複性工作

當應用有時可能需要定期運行某些任務,例如:定期備份、下載應用中的新鮮內容,或者上傳日誌到服務器,此時需要將 PeriodicWorkRequest 用於這種需要定期執行的任務

    定期工作請求的示例代碼:
            Constraints constraints = new Constraints.Builder()
                    .setRequiresCharging(true)
                    .build();

            PeriodicWorkRequest saveRequest =
                    new PeriodicWorkRequest.Builder(SaveImageFileWorker.class, 1, TimeUnit.HOURS)
                              .setConstraints(constraints)
                              .build();

            WorkManager.getInstance(myContext)
                .enqueue(saveRequest);

10. 唯一工作

 

當需要創建一個唯一工作鏈,可以使用:
WorkManager.beginUniqueWork(String, ExistingWorkPolicy, OneTimeWorkRequest) 代替 beginWith();

 

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