如何將WorkManager與RxJava一起使用

Android心路歷程發表於2019-04-15

注:因翻譯問題文中所有工作經理即為WorkManager

工作經理是Android架構元件之一。它允許執行可延遲的後臺工作,即使在app退出或裝置重啟後也會執行。

由於WorkManager是Jetpack的一部分,因此它是在考慮MVVM架構和LiveData的情況下建立的。但是我們所有人都在大量使用RxJava?我們應該接受WorkManager不適合我們嗎?

當然不是!在本文中,我將向您展示如何將WorkManager與RxJava一起使用以及您可能遇到的問題。另外,我建立了庫來幫助你解決這些問題?。

(我建立的庫RxWorkManagerObservers允許以被動的方式觀察在WorkManager中排隊的工作的狀態。如果您只對庫的描述感興趣,可以跳過本文的開頭直接到最後部分。)

何時使用WorkManager?

WorkManager處理可延遲的後臺工作(可能不會立即執行),但無論應用程式是退出還是裝置重新啟動,都需要保證執行。

對於從API獲取資料並將其顯示給使用者來說,WorkManager絕對不是一個好的選擇。該任務不需要在程式死亡中存活,因為在使用者退出應用程式後獲取的結果將無效。在這種情況下,最好使用其他東西,例如Kotlin的協同程式或RxJava。

但是,如果要在後臺同步某些資料,傳送日誌或上傳照片 - WorkManager將是一個很好的選擇。

建立後臺任務

要定義後臺任務,您需要建立擴充套件的類Worker。在doWork()方法中指定應該執行的操作並返回結果(成功,失敗或重試)。

doWork()在由後臺提供的後臺執行緒上同步執行的WorkManager,所以在大多數情況下,不需要擔心這裡的執行緒。

列入工作

要執行工作,首先,您必須建立WorkRequest。一次性WorkRequest使用OneTimeWorkRequestBuilder。它允許建立將由一次執行的工作請求WorkManager

建立工作請求後,可以通過呼叫enqueue方法來安排工作請求WorkManager

使用上面的程式碼段,將立即安排工作請求。但是,WorkManager具有更多功能。您可以安排在滿足特定約束時執行任務(例如,電話正在充電),使用PeriodicWorkRequestBuilder或連結多個工作請求建立重複工作。所有這些功能都非常棒,我強烈建議您在文件中閱讀它們。

傳遞和檢索工作人員的資料

另一個令人驚奇的功能是WorkManager允許您將輸入資料傳遞給worker並從中返回輸出資料。

例如,您可以建立將使用者名稱作為輸入的worker,處理資料並將使用者識別符號作為輸出返回。

輸入資料可以使用workDataOf()方法(work-runtime-ktx的一部分)建立,但您也可以Data.Builder直接使用。建立的資料將傳遞給OneTimeWorkRequestBuilderusing setInputData(Data)方法。

建立一個被動的工人

如果你想在你的工作者中使用observable,那也不是問題。為了提供WorkManager和RxJava之間的互操作性,work-rxjava2依賴性是由Android團隊建立的。

androidx.work:work-rxjava2:$work_versiongradle檔案中包含後,您可以建立擴充套件RxWorker的worker。它類似於普通工作者,但doWork()它沒有返回a Result ,而是返回createWork()方法Single<Result>。因此,您可以輕鬆地在其中使用反應函式和運算子。

關於RxWorker的重要說明:

  • 在主執行緒上呼叫createWork()方法,但在後臺執行緒上訂閱返回的單元
  • 您無需擔心處置Observer,因為RxWorker會在工作停止時自動處理它
  • 返回Single的值Result.failure()和單個返回錯誤將導致worker進入失敗狀態

觀察工作狀態並檢索輸出資料

排隊後WorkRequest,WorkManager允許檢查其狀態。此資訊儲存在一個WorkInfo物件中,該物件包含工作ID,標記,其當前狀態和輸出資料(如果已經返回)。

下圖顯示了工作和轉換的可能狀態。

致謝:使用WorkManager(Android Dev Summit '18)

觀察工作有三種不同的方式:

1您可以使用以下方法檢索WorkInfo特定WorkRequest於其ID 的特定內容:

  • WorkManager.getWorkInfoByIdLiveData(UUID)- 允許觀察對狀態變化的WorkInfo使用LiveData和反應
  • WorkManager.getWorkInfoById(UUID) - returns ListenableFuture<WorkInfo> - Future允許新增偵聽器的a ,當具有特定id的工作完成時將通知該偵聽器。

2您還可以檢索具有特定標記的所有工作請求的WorkInfo物件。工作標記在建立工作請求期間傳遞:

然後,您可以觀察WorkRequest使用給定標記建立的s 列表的狀態:

  • 使用LiveData<List<WorkInfo>>檢索的WorkManager.getWorkInfosByTagLiveData(String)

要麼

  • 使用ListenableFuture<List<WorkInfo>>返回的WorkManager.getWorkInfosByTag(String)

3對於一項獨特的工作,還有一組非常相似的方法:

  • WorkManager.getWorkInfosForUniqueWorkLiveData(String)這允許觀察WorkRequests狀態LiveData<List<WorkInfo>>

要麼

  • WorkManager.getWorkInfosForUniqueWork(String)返回一個ListenableFuture<List<WorkInfo>>

獨立工作的建立方式與常規工作相同,但是使用特定ID和現有工作策略排隊。更多關於獨特的工作,你可以看這裡

反應觀察者呢?

如果你是像我這樣的RxJava粉絲你可能會感到失望的是沒有選擇觀察WorkRequests使用Observable。我非常支援使應用程式的架構連貫,因此程式碼易於學習和推理。因此,我認為這可能是一個問題,你只能用LiveData(或ListenableFuture)來觀察工作的狀態。

這就是為什麼我建立了允許處理這個問題的庫?。

PaulinaSadowska / RxWorkManagerObservers
通過在GitHub上建立一個帳戶,為PaulinaSadowska / RxWorkManagerObservers開發做出貢獻。github.com

這個圖書館裡有什麼?

為了允許以被動的方式觀察排隊的工作,我建立了一組擴充套件函式WorkManager。這些函式中的每一個都轉換LiveDataObservable發出DataWorkRequest整個WorkInfo物件返回的物件。

在引擎蓋下,我使用WorkManager返回的功能LiveDataLiveData使用observeForever(Observer)該檢索只能在主執行緒上呼叫檢索。因此,必須在主執行緒上訂閱Observable從此庫中的每個函式返回的內容當然,實際工作仍將在WorkManager指定的後臺執行緒上執行

該庫不依賴於work-rxjava2因此您不必包含它。如果您使用RxWorker,Worker,CoroutineWorker或任何其他自定義ListenableWorker並不重要 -  它可以使用所有這些

通過id觀察資料

如果您希望通過其ID檢視特定的工作請求,並且您需要的唯一資訊是工作是成功,失敗還是取消,您可以使用getWorkDataByIdSingle(UUID)擴充套件功能:

如果onSuccess使用Data來自的物件呼叫工作完成WorkInfo(如果工作不返回,則可能為空)。

如果工作失敗或被取消,onError則使用WorkFailedException或呼叫WorkCancelledException

通過id觀察WorkInfo

如果在工作狀態發生變化時需要更新,您可以使用以下功能觀察它:

每當工作狀態發生變化時,observable都會發出WorkInfo物件。如果工作成功,它會發出值並完成。如果它失敗或被取消 - 它會發出WorkInfo值,然後發出錯誤(WorkFailedExceptionWorkCancelledException)。

按標籤觀察資料

您還可以使用以下函式通過特定標記觀察工作請求:

當一些s完成時,它DataWorkInfo物件中發出WorkRequest

預設情況下,如果其中一個WorkRequest失敗或被取消,onError則不會發出(但不會從工作中收到任何值)。這是因為我想允許觀察WorkRequests,即使其中一個請求失敗或被取消。但是,如果您希望Observable失敗,如果其中一個WorkRequest失敗 - 您可以通過將ignoreError標誌設定為false(預設情況下為true)來執行此操作。

觀察獨特的工作

您還可以使用以下功能觀察Unique工作:

它的行為就像前一個方法(getWorkDatasByTagObservable)建立的observable ,但是使用getWorkInfosForUniqueWorkLiveData而不是getWorkInfosByTagLiveData 獲取LiveData

TL; DR

  • 工作經理搖滾?
  • 您可以Observers在使用work-rxjava2依賴項的worker中使用。然後你只是擴充套件RxWorker而不是Worker
  • 預設情況下,只能WorkRequestLiveData或觀察s ListenableFuture
  • 使用RxWorkManagerObservers庫,您可以以被動方式觀察s。它轉變到或在引擎蓋下。 WorkRequestLiveDataObservableSingle
  •  

 

+qq群457848807:。獲取以上高清技術思維圖,以及相關技術的免費視訊學習資料

相關文章