Android開發(fā)Jetpack組件WorkManager用例詳解
一、簡介
WorkManager 用于處理 Android 后臺任務。我們只需要設置好任務內容、何時執(zhí)行,剩下的工作就可以完全交給系統處理。它會自動向下兼容,在不同的 Android 版本上采用不同的實現方案。
由于是交給系統調度的,它可以保證應用退出甚至手機重啟后,任務依然能夠得到執(zhí)行。WorkManager 很適合執(zhí)行一些定期和服務器交互的任務,比如周期性的同步數據等等。并且,WorkManager 還支持周期性任務、鏈式任務。
需要注意的是,WorkManager 不能保證任務一定能夠準時執(zhí)行,這是因為系統為了減少電量消耗,會將觸發(fā)事件臨近的幾個任務放在一起執(zhí)行,以減少 CPU 被喚醒的次數,延長電池使用時間。
另外,在國產手機上 WorkManager 可能無法正常運行,這是因為絕大多數手機廠商定制 Android 系統時,會添加一個“一鍵關閉”的功能,這樣被殺死后的應用程序,既無法接收廣播,也不能運行 WorkManager 的后臺任務。國產手機增加此功能也是迫于無奈,主要是因為市面上有太多的惡意應用想要霸占后臺。所以,我們在國產手機上不要使用 WorkManager 去實現核心功能。
二、導入
在 app/build.gradle 中添加依賴:
implementation 'androidx.work:work-runtime:2.3.2'
三、基本使用
WorkManager 的用法分為三步:
- 定義一個后臺任務
- 配置任務運行條件
- 將任務傳給 WorkManager
3.1 定義后臺任務
創(chuàng)建一個 SimpleWorker 類,繼承自 Worker:
class SimpleWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
Log.d("~~~", "do something")
return Result.success()
}
}
Result.success()表示任務執(zhí)行成功
Result.failure() 表示任務執(zhí)行失敗
Result.retry() 表示任務需要重試。這個方法需要配合任務重試配置一起使用
3.2 配置任務運行條件
3.2.1 只需執(zhí)行一次的任務
使用 OneTimeWorkRequest 構建只需執(zhí)行一次的任務
val request = OneTimeWorkRequest.Builder(SimpleWorker::class.java).build()
3.2.2 周期性執(zhí)行的任務
使用 PeriodicWorkRequest 構建周期性執(zhí)行的任務
val request = PeriodicWorkRequest.Builder(SimpleWorker::class.java, 15, TimeUnit.MINUTES).build()
為了減少耗電量,PeriodicWorkRequest 要求任務執(zhí)行周期不得短于十五分鐘,查看源碼可以發(fā)現,如果傳入的值短于十五分鐘,系統會打印一條警告,然后自動將周期設置成十五分鐘:
public static final long MIN_PERIODIC_INTERVAL_MILLIS = 15 * 60 * 1000L; // 15 minutes.
/**
* Sets the periodic interval for this unit of work.
*
* @param intervalDuration The interval in milliseconds
*/
public void setPeriodic(long intervalDuration) {
if (intervalDuration < MIN_PERIODIC_INTERVAL_MILLIS) {
Logger.get().warning(TAG, String.format(
"Interval duration lesser than minimum allowed value; Changed to %s",
MIN_PERIODIC_INTERVAL_MILLIS));
intervalDuration = MIN_PERIODIC_INTERVAL_MILLIS;
}
setPeriodic(intervalDuration, intervalDuration);
}
3.3 將任務傳給 WorkManager
WorkManager.getInstance(this).enqueue(request)
這就是 WorkManager 的基本使用。
四、高級配置
4.1 設置任務延遲執(zhí)行
通過 setInitialDelay 方法設置延遲時間
val request = OneTimeWorkRequest.Builder(SimpleWorker::class.java) .setInitialDelay(5, TimeUnit.MINUTES) .build()
4.2 給任務添加標簽
通過 addTag 方法添加標簽:
val request = OneTimeWorkRequest.Builder(SimpleWorker::class.java)
.addTag("simple")
.build()
添加標簽的作用是,方便我們根據標簽取消任務。
4.3 取消任務
4.3.1 根據標簽取消任務
WorkManager.getInstance(this).cancelAllWorkByTag("simple")
4.3.2 根據 request 的 id 取消任務
WorkManager.getInstance(this).cancelWorkById(request.id)
4.3.3 取消所有任務
WorkManager.getInstance(this).cancelAllWork()
4.4 任務重試
通過 setBackoffCriteria 配置任務重試:
val request = OneTimeWorkRequest.Builder(SimpleWorker::class.java) ? ? .setBackoffCriteria(BackoffPolicy.LINEAR, 10, TimeUnit.SECONDS) ? ? .build()
前文說到,Result.retry() 表示任務需要重試,這個方法需要配合任務重試配置一起使用。任務重試配置就是指這個 setBackoffCriteria 方法,它傳入了三個值,第二個值和第三個值表示重試時間配置。第一個值表示重試延遲的形式,有兩個值可供選擇:
- BackoffPolicy.LINEAR 重試時間每次呈線性增長,按照此例中的配置,每次重試時間就是 10s,20s,30s,40s…
- BackoffPolicy.EXPONENTIAL 重試時間每次呈指數級增長,按照此例中的配置,每次重試時間就是 10s,20s,40s,80s…
4.5 監(jiān)聽任務結果
WorkManager.getInstance(this).getWorkInfoByIdLiveData(request.id).observe(this) {
? ? Log.d("~~~", "state = ${it.state}, tags = ${it.tags.toList()}")
? ? when (it.state) {
? ? ? ? WorkInfo.State.SUCCEEDED -> Log.d("~~~", "success")
? ? ? ? WorkInfo.State.FAILED -> Log.d("~~~", "fail")
? ? ? ? WorkInfo.State.RUNNING -> Log.d("~~~", "running")
? ? ? ? WorkInfo.State.ENQUEUED -> Log.d("~~~", "enqueued")
? ? ? ? WorkInfo.State.CANCELLED -> Log.d("~~~", "cancelled")
? ? ? ? WorkInfo.State.BLOCKED -> Log.d("~~~", "blocked")
? ? }
}首先通過 getWorkInfoByIdLiveData 獲得任務信息的 LiveData<WorkInfo> 數據,然后觀察此數據即可。也可以通過 getWorkInfosByTagLiveData 獲得相同 Tag 的 LiveData<List<WorkInfo>>,觀察這個任務信息列表。通過 WorkInfo 的 getState 方法獲取任務狀態(tài),主要用到的狀態(tài)有 WorkInfo.State.SUCCEEDED 和 WorkInfo.State.FAILED,標志著任務的成功和失敗。
4.6 傳遞數據
val request = OneTimeWorkRequest.Builder(SimpleWorker::class.java)
? ? .setInputData(Data.Builder().apply {
? ? ? ? putString("key", "value")
? ? }.build())
? ? .build()SimpleWorker 類中讀取此數據:
inputData.getString("key")4.7 鏈式任務
val first = OneTimeWorkRequest.Builder(SimpleWorker::class.java) ? ? .build() val second = OneTimeWorkRequest.Builder(SimpleWorker::class.java) ? ? .build() val third = OneTimeWorkRequest.Builder(SimpleWorker::class.java) ? ? .build() WorkManager.getInstance(this) ? ? .beginWith(first) ? ? .then(second) ? ? .then(third) ? ? .enqueue()
通過 beginWith 發(fā)起鏈式任務,然后后綴 then 即可,任務會按照連接順序依次執(zhí)行。WorkManager 要求必須在上一個任務執(zhí)行成功后,才會執(zhí)行下一個任務。也就是說任何一個任務的失敗都會導致鏈式任務的中斷。
以上就是Android開發(fā)Jetpack組件WorkManager用例詳解的詳細內容,更多關于Android Jetpack組件WorkManager的資料請關注腳本之家其它相關文章!
相關文章
深入分析Android NFC技術 android nfc開發(fā)
本篇文章我們對android開發(fā)中nfc技術做了全面的原理分析以及實現過程,需要的讀者們一起參考一下吧。2017-11-11
Android控件RefreshableView實現下拉刷新
這篇文章主要為大家詳細介紹了Android控件RefreshableView實現下拉刷新,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11
Android Drawerlayout側拉欄事件傳遞問題的解決方法
這篇文章主要為大家詳細介紹了Android Drawerlayout側拉欄事件傳遞問題的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11
Android 如何實現exclude aar包中的某個jar包
這篇文章主要介紹了Android 如何實現exclude aar包中的某個jar包,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03

