如何使用WorkManager執行後臺任務(上)
0x00 簡述
-
支援非同步一次性或週期任務
-
支援網路、儲存空間以及電量狀態等約束
-
可使用鏈式的呼叫方式來執行任務,也包括並行任務處理
-
一個工作任務的執行結果可以作為下一個任務的輸入
-
相容API 14 以上
-
可以支援Google play services
-
支援LiveData
0x01 理論篇——重要的類
WorkManager庫中有一些非常重要的類,這些類幫助你構建後臺執行的工作任務:
-
Worker
:這是一個抽象類,它表示一個工作任務,繼承這個類實現doWork()
方法,這裡就是實現執行任務的主要邏輯。 -
WorkRequest
:表示一個工作任務請求,指定執行哪個Work
,它還可以設定任務執行的約束條件。每一個WorkRequest
都有一個自動生成的唯一ID。使用這個ID可以取消任務的執行,或者取得當前任務的執行狀態。WorkRequest
也是一個抽象類,使用的時候是框架庫中提供的子類OneTimeWorkRequest
和PeriodicWorkRequest
類,分別代表一次性任務和週期任務-
WorkRequest.Builder
:這是一個建立工作任務請求的輔助工具類。它有兩個具體的實現:OneTimeWorkRequest.Builder
類和PeriodicWorkRequest.Builder
類,可以分別建立相應的任務請求例項。 -
Constraints
:它表示工作任務執行的約束條件。指的是在哪一些系統條件下(例如只有網路連線情況下),這個工作任務會被執行。同樣地,建立Constraints
也有Builder
方法:Constraints.Builder
。約束類是可以在使用WorkRequest.Builder
建立的時候進行傳遞給WorkRequest
。
-
-
WorkManager
:工作工作管理員,它是用於管理工作任務的請求佇列的類。通過它可以把一個WorkRequest
加入到任務佇列中,然後根據系統的資源和約束條件對工作任務進行排程。 -
WorkStatus
:工作狀態類,它包含了工作任務當前的狀態資訊。WorkManager
為每一個WorkRequest
都提供了LiveData
物件,而LiveData
物件又持有WorkStatus
資訊,因此通過LiveData
可以監聽到當前任務的狀態資訊,並且獲取到任務結束後的執行結果。
通過上面的描述,可以簡單的畫出下面的關係圖:
0x02 實踐篇——工作流
假設我們在開發一個圖片相關的APP,這個應用需要期地壓縮它儲存的圖片。我們使用WorkManager
來實現這個需求。這種情況,我們不關心壓縮任務什麼時候開始,只要開啟一個壓縮任務,其他的就交給WorkManager
了。
-
定義Worker
我們首先要定義一個Worker
類,並重寫doWork()
方法,這裡定義瞭如何執行任務的具體邏輯。例如在此例子中,myCompress()
就是具體的執行任務的邏輯。
class CompressWorker(context : Context, params : WorkerParameters) : Worker(context, params) { override fun doWork(): Result { // Do the work here--in this case, compress the stored images. // In this example no parameters are passed; the task is // assumed to be "compress the whole library." myCompress() // Indicate success or failure with your return value: return Result.SUCCESS // (Returning RETRY tells WorkManager to try this task again // later; FAILURE says not to try again.) } }
doWork()
執行後還可以返回執行的結果:Result.SUCCESS
、Result.FAILURE
和Result.RETRY
分別表示成功、失敗、重試。
-
建立WorkRequest
使用WorkRequest
的子類,根據具體業務建立對應的請求例項。例如本例中,使用一次性任務來構建請求。然後把任務請求加入到WorkManager
管理的佇列中。
val compressionWork = OneTimeWorkRequest.Builder<CompressWorker>().build() WorkManager.getInstance().enqueue(compressionWork)
這樣這個任務就交給WorkManager
了,任務管理者根據當前系統情況(是否充電、網路狀態等等)對任務進行排程。如果沒有給WorkRequest
指定約束條件,那麼這個任務會馬上執行。如果需要得到這個任務的狀態,可以通過LiveData<WorkStatus>
來監聽。
WorkManager.getInstance().getStatusById(compressionWork.id) .observe(lifecycleOwner, Observer { workStatus -> // Do something with the status if (workStatus != null && workStatus.state.isFinished) { // ... } })
-
任務約束
可以給一個任務指定約束條件。例如,可以在裝置空閒的時候、或者充電的時候執行任務。這種情況,可以使用Constraints.Builder
來建立一個約束條件例項,然後傳遞到WorkRequest
中。
// Create a Constraints object that defines when the task should run val myConstraints = Constraints.Builder() .setRequiresDeviceIdle(true) .setRequiresCharging(true) // Many other constraints are available, see the // Constraints.Builder reference .build() // ...then create a OneTimeWorkRequest that uses those constraints val compressionWork = OneTimeWorkRequestBuilder<CompressWorker>() .setConstraints(myConstraints) .build()
最後,還是呼叫WorkManager
的enqueue
方法將WorkRequest
加入佇列。這時候,WorkManager
在執行任務的時候就會考慮約束條件的情況。
-
取消任務
取消任務需要一個任務ID,可以通過WorkRequest
來獲取。然後呼叫WorkManager
的cancelWorkById
方法來取消任務的執行。
val compressionWorkId:UUID = compressionWork.getId() WorkManager.getInstance().cancelWorkById(compressionWorkId)
-
給任務設定Tag
可以給一組任務設定一個Tag。在建立 WorkRequest
的時候,可以執行給它指定一個Tag;而另一個任務請求也可以設定相同的Tag。
val cacheCleanupTask = OneTimeWorkRequest.Builder<MyCacheCleanupWorker>() .addTag("one-tag") .build() val loadImageTask = OneTimeWorkRequest.Builder<MyImageLoadWorker>() .addTag("one-tag") .build()
WorkManager
提供了很多有用的API操作這些相同Tag的任務。例如,WorkManager.cancelAllWorkByTag()
可以取消具有相同Tag的一組任務;還可以通過WorkManager.getStatusesByTag()
獲取一組任務的狀態列表。
-
週期任務
有些業務場景是需要重複執行一個任務的。例如,在一個圖片應用中,可能會有一個定期檢查需要壓縮圖片的任務。這時候可使用到 PeriodicWorkRequest.Builder
來建立一個週期任務。跟一次性任務一樣,通過WorkManager.enqueue()
方法加入到工作任務佇列中。
val photoCheckBuilder = PeriodicWorkRequest.Builder<PhotoCheckWorker>(12, TimeUnit.HOURS) // ...if you want, you can apply constraints to the builder here... // Create the actual work object: val photoCheckWork = photoCheckBuilder.build() // Then enqueue the recurring task: WorkManager.getInstance().enqueue(photoCheckWork)
接下來的事情就交給 WorkManager
了。
0x03 引用
https://developer.android.com/topic/libraries/architecture/workmanager/basics
相關文章
- Android Jetpack – 使用 WorkManager 管理後臺任務AndroidJetpack
- Android Jetpack - 使用 WorkManager 管理後臺任務AndroidJetpack
- 使用screen後臺執行任務
- php後臺定時執行任務PHP
- linux後臺執行和關閉、檢視後臺任務Linux
- 例項後臺執行訓練或任務
- .NET寶藏API之:IHostedService,後臺任務執行API
- Day10 鴻蒙,Ability全家桶(二)如何後臺執行任務鴻蒙
- ASP.NET Core 2.1 : 十一. 如何在後臺執行一個任務ASP.NET
- Android WorkManager 定時任務Android
- IDEA上執行Flink任務Idea
- 大資料開發-linux後臺執行,關閉,檢視後臺任務大資料Linux
- 如何使用cron任務每隔2天在固定時間執行任務
- 後臺任務
- 如何避免任務重複執行
- Linux 任務後臺執行軟體【即:終端複用器】之---screenLinux
- Mac Redis 服務後臺執行MacRedis
- HarmonyOS 後臺任務管理開發指南上線!
- 如何在 Flutter 建立一個後臺任務Flutter
- dot net core使用BackgroundService執行一個後臺服務
- 使用 Bash 自動執行復雜任務
- Spring Boot使用執行緒池處理事務任務Spring Boot執行緒
- [linux] 使用Screen後臺執行命令Linux
- .net使用Task多執行緒執行任務 .net限制執行緒數量執行緒
- Linux 以執行使用者執行定時任務後,報錯 Failed to cache access tokenLinuxAI
- Linux 執行定時任務後,Laravel 專案報錯LinuxLaravel
- 微任務和巨集任務哪個先執行
- 同步任務與非同步任務執行順序非同步
- laravel框架任務排程(定時執行任務)Laravel框架
- php:多程式執行任務PHP
- 一篇文章搞清spark任務如何執行Spark
- Linux後臺執行Linux
- shell後臺執行
- netcore後臺任務注意事項NetCore
- Android後臺任務(HandlerThread、AsyncTask、IntentService)AndroidthreadIntent
- Linux任務的前後臺管理Linux
- iOS App 後臺任務的坑iOSAPP
- Springboot-之定時任務,啟動執行任務Spring Boot