注意: 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();