日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jetpack之workManager官方文档解析

發布時間:2023/12/18 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jetpack之workManager官方文档解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

基礎介紹

workmanager是一個可延期的后臺異步任務,可以用來取代以前的android后臺調度任務

通俗的講就是可以用來做后臺異步任務,那他有什么優勢呢,和以前的后臺api方法相比有什么區別呢?

帶著這倆個問題開始往下看

兼容性

首先workmanager兼容性很好,包括 FirebaseJobDispatcher、GcmNetworkManager 和 JobScheduler

都可以替換成workmanager,同時支持 API 級別 14,對電量續航也做了優化(省電)

基礎功能

創建方式:通過單例創建workmanager,enqueue方法將任務加入隊列

val myWorkRequest = ... WorkManager.getInstance(myContext).enqueue(myWorkRequest)

任務(workrequest)是抽象基類,有倆個子類

OneTimeWorkRequest和PeriodicWorkRequest

OneTimeWorkRequest 適用于調度非重復性工作,而 PeriodicWorkRequest 則更適合調度以一定間隔重復執行的工作。

一次性工作:

val myWorkRequest = OneTimeWorkRequest.from(MyWork::class.java)

如果是復雜一點的一次性工作可以用構建器,可以在這里對你的任務添加一些策略

val uploadWorkRequest: WorkRequest =OneTimeWorkRequestBuilder<MyWork>()// Additional configuration.build()

定期性工作

val saveRequest =PeriodicWorkRequestBuilder<SaveImageToFileWorker>(1, TimeUnit.HOURS)// Additional configuration.build() //工作的運行時間間隔定為一小時。 //可以定義的最短重復間隔是 15 分鐘

request由work類組成。work類就是具體執行流程的類

如下TestWork類繼承Workr類,實現doWork方法,在里面上傳圖片

class TestWorker(appContext: Context, workerParams: WorkerParameters):Worker(appContext, workerParams) {override fun doWork(): Result {// Do the work here--in this case, upload the images.uploadImages()// Indicate whether the work finished successfully with the Resultreturn Result.success()} }doWork() 返回的 Result 會通知 WorkManager 服務工作是否成功,以及工作失敗時是否應重試工作。 Result.success():工作成功完成。 Result.failure():工作失敗。 Result.retry():工作失敗,應根據其重試政策在其他時間嘗試。

到這里,一個簡單的workmanager就介紹完了,包括workmanager的創建方式,request的組成,work的創建

接下來是workmanger的一些配置

約束

可以給任務添加約束(比如在wifi條件下才運行,在充電狀態下才運行)

val constraints = Constraints.Builder().setRequiredNetworkType(NetworkType.UNMETERED).setRequiresCharging(true).build()val myWorkRequest: WorkRequest =OneTimeWorkRequestBuilder<MyWork>().setConstraints(constraints).build() //可以添加的約束類型如下

延遲工作

下面的示例為延遲10分鐘

val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>().setInitialDelay(10, TimeUnit.MINUTES).build()

調度

對于一組完整的異步任務,可以運行一次,也可以重復運行,對每一組任務進行命名,用來單獨操作他們

//給一個單獨的work添加標識 val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>().addTag("cleanup").build() //可以通過WorkManager.cancelAllWorkByTag(String)取消任務 //可以通過WorkManager.getWorkInfosByTag(String)獲取這個任務,得到一個WorkInfo對象 //可以通過workManager.getWorkInfosByTagLiveData(String)得到一個livedata,當這個對象的tag的work執行完成之后,這個livedata會觸發

靈活的重試機制

LINEAR和EXPONENTIAL倆種策略

當你在work的dowork方法中返回Result.retry()的時候,會進行重試機制

val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>().setBackoffCriteria(BackoffPolicy.LINEAR,OneTimeWorkRequest.MIN_BACKOFF_MILLIS,TimeUnit.MILLISECONDS).build() //MIN_BACKOFF_MILLIS為10秒 //LINEAR策略,每次嘗試重試的時候,重試間隔都會增加10秒,20,30,40類推 //如果是EXPONENTIAL策略,那么重試時長是20、40、80 秒,以此類推。

work中的數據傳遞

// Define the Worker requiring input class UploadWork(appContext: Context, workerParams: WorkerParameters): Worker(appContext, workerParams) {override fun doWork(): Result {val imageUriInput =inputData.getString("IMAGE_URI") ?: return Result.failure()uploadFile(imageUriInput)return Result.success()}... }// Create a WorkRequest for your Worker and sending it input val myUploadWork = OneTimeWorkRequestBuilder<UploadWork>().setInputData(workDataOf("IMAGE_URI" to "http://...")).build()//還可以通過 Result.success(outputData)將數據傳遞給下一個work

工作狀態

一次性工作狀態

對于 one-time 工作請求,工作的初始狀態為 ENQUEUED。

在 ENQUEUED 狀態下,您的工作會在滿足其 Constraints 和初始延遲計時要求后立即運行。接下來,該工作會轉為 RUNNING 狀態,然后可能會根據工作的結果轉為 SUCCEEDED、FAILED 狀態;或者,如果結果是 retry,它可能會回到 ENQUEUED 狀態。在此過程中,隨時都可以取消工作,取消后工作將進入 CANCELLED 狀態。

SUCCEEDED、FAILED 和 CANCELLED 均表示此工作的終止狀態。如果您的工作處于上述任何狀態,WorkInfo.State.isFinished() 都將返回 true。

定期工作的狀態

成功和失敗狀態僅適用于一次性工作和鏈式工作。定期工作只有一個終止狀態 CANCELLED。這是因為定期工作永遠不會結束。每次運行后,無論結果如何,系統都會重新對其進行調度。圖 2 描述了定期工作的精簡狀態圖。

唯一工作

確保在某一個時刻只有一個相同的實例存在

  • [WorkManager.enqueueUniqueWork()](https://developer.android.google.cn/reference/androidx/work/WorkManager#enqueueUniqueWork(java.lang.String, androidx.work.ExistingWorkPolicy, androidx.work.OneTimeWorkRequest))(用于一次性工作)
  • [WorkManager.enqueueUniquePeriodicWork()](https://developer.android.google.cn/reference/androidx/work/WorkManager#enqueueUniquePeriodicWork(java.lang.String, androidx.work.ExistingPeriodicWorkPolicy, androidx.work.PeriodicWorkRequest))(用于定期工作)

這兩種方法都接受 3 個參數:

  • uniqueWorkName - 用于唯一標識工作請求的 String。
  • existingWorkPolicy - 此 enum 可告知 WorkManager 如果已有使用該名稱且尚未完成的唯一工作鏈,應執行什么操作。如需了解詳情,請參閱沖突解決政策。
  • work - 要調度的 WorkRequest。
val sendLogsWorkRequest =PeriodicWorkRequestBuilder<SendLogsWorker>(24, TimeUnit.HOURS).setConstraints(Constraints.Builder().setRequiresCharging(true).build()).build() WorkManager.getInstance(this).enqueueUniquePeriodicWork("sendLogs",ExistingPeriodicWorkPolicy.KEEP,sendLogsWorkRequest )

上述代碼在 sendLogs 作業已處于隊列中的情況下運行,系統會保留現有的作業,并且不會添加新的作業

ExistingPeriodicWorkPolicy有三種選項

  • REPLACE:用新工作替換現有工作。此選項將取消現有工作。

  • KEEP:保留現有工作,并忽略新工作。

  • APPEND:將新工作附加到現有工作的末尾。此政策將導致您的新工作鏈接到現有工作,在現有工作完成后運行。

  • APPEND_OR_REPLACE 功能類似于 APPEND,不過它并不依賴于先決條件工作狀態。即使現有工作變為 CANCELLED 或 FAILED 狀態,新工作仍會運行。

狀態監聽

可以通過三種方式獲取查詢work

// by id workManager.getWorkInfoById(syncWorker.id) // ListenableFuture<WorkInfo>// by name workManager.getWorkInfosForUniqueWork("sync") // ListenableFuture<List<WorkInfo>>// by tag workManager.getWorkInfosByTag("syncTag") // ListenableFuture<List<WorkInfo>>

該查詢會返回 WorkInfo 對象的 ListenableFuture,該值包含工作的 id、其標記、其當前的 State 以及通過 Result.success(outputData) 設置的任何輸出數據

下面的代碼展示了,當syncWorker完成后,顯示一個消息

workManager.getWorkInfoByIdLiveData(syncWorker.id).observe(viewLifecycleOwner) { workInfo ->if(workInfo?.state == WorkInfo.State.SUCCEEDED) {Snackbar.make(requireView(),R.string.work_completed, Snackbar.LENGTH_SHORT).show()} }

復雜的work狀態查詢

以下示例說明了如何查找帶有“syncTag”標記、處于 FAILED 或 CANCELLED 狀態,且唯一工作名稱為“preProcess”或“sync”的所有工作。

val workQuery = WorkQuery.Builder.fromTags(listOf("syncTag")).addStates(listOf(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED)).addUniqueWorkNames(listOf("preProcess", "sync")).build()val workInfos: ListenableFuture<List<WorkInfo>> = workManager.getWorkInfos(workQuery) WorkQuery` 中的每個組件(標記、狀態或名稱)與其他組件都是 `AND` 邏輯關系。組件中的每個值都是 `OR` 邏輯關系。例如:`(name1 OR name2 OR ...) AND (tag1 OR tag2 OR ...) AND (state1 OR state2 OR ...)

WorkQuery 也適用于等效的 LiveData 方法 getWorkInfosLiveData()

取消和停止工作

// by id workManager.cancelWorkById(syncWorker.id)// by name workManager.cancelUniqueWork("sync")// by tag workManager.cancelAllWorkByTag("syncTag")

觀察進度

在work的dowork方法中通過

setProgress(firstUpdate)//設置進度

觀察進度

WorkManager.getInstance(applicationContext)// requestId is the WorkRequest id.getWorkInfoByIdLiveData(requestId).observe(observer, Observer { workInfo: WorkInfo? ->if (workInfo != null) {val progress = workInfo.progressval value = progress.getInt(Progress, 0)// Do something with progress information}})

鏈接工作

您可以使用 WorkManager 創建工作鏈并將其加入隊列。工作鏈用于指定多個依存任務并定義這些任務的運行順序。當您需要以特定順序運行多個任務時,此功能尤其有用。

如需創建工作鏈,您可以使用 WorkManager.beginWith(OneTimeWorkRequest) 或 WorkManager.beginWith(List),這會返回 WorkContinuation 實例。

然后,可以使用 WorkContinuation 通過 then(OneTimeWorkRequest) 或 then(List) 添加依存 OneTimeWorkRequest。 .

每次調用 WorkContinuation.then(...) 都會返回一個新的 WorkContinuation 實例。如果添加了 OneTimeWorkRequest 實例的 List,這些請求可能會并行運行。

最后,您可以使用 WorkContinuation.enqueue() 方法對 WorkContinuation 工作鏈執行 enqueue() 操作。

下面我們來看一個示例。在本例中,有 3 個不同的工作器作業配置為運行(可能并行運行)。然后這些工作器的結果將聯接起來,并傳遞給正在緩存的工作器作業。最后,該作業的輸出將傳遞到上傳工作器,由上傳工作器將結果上傳到遠程服務器。

WorkManager.getInstance(myContext)// Candidates to run in parallel.beginWith(listOf(plantName1, plantName2, plantName3))// Dependent work (only runs after all previous work in chain).then(cache).then(upload)// Call enqueue to kick things off.enqueue()

如果想將plantName1, plantName2, plantName3work的輸出作為下一個work cache的輸入。那么就需要用到輸入合并器

WorkManager 提供兩種不同類型的 InputMerger:

  • OverwritingInputMerger 會嘗試將所有輸入中的所有鍵添加到輸出中。如果發生沖突,它會覆蓋先前設置的鍵。
  • ArrayCreatingInputMerger 會嘗試合并輸入,并在必要時創建數組。

也可以創建 InputMerger 的子類來編寫自己的用例。

by the last最后說一下

請注意,Worker.doWork() 是同步調用 - 您將會以阻塞方式完成整個后臺工作,并在方法退出時完成工作。如果您在 doWork() 中調用異步 API 并返回 Result,則回調可能無法正常運行。如果您遇到這種情況,請考慮使用 ListenableWorker(請參閱在 ListenableWorker 中進行線程處理)。

總結

以上是生活随笔為你收集整理的jetpack之workManager官方文档解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。