網站首頁 編程語言 正文
WorkManager和Service并不相同,也沒有直接的聯系。Service是Android系統四大組件之一,它沒有被銷毀的情況下是一直保持在后臺運行的。而WorkManager只是一個處理定時任務的工具,它可以保證即使在應用退出甚至手機重啟的情況下,之前注冊的任務仍然將會得到執行,因此WorkManager很適合用于執行一些定期和服務器進行交互的任務,比如周期性地同步數據等等。
使用WorkManager注冊的周期性任務不能保證一定會準時執行,這是因為系統為了減少電量消耗,可能會將觸發時間臨近的幾個任務放在一起執行,這樣可以大幅度減少CPU被喚醒的次數,從而有效延長電池的使用時間。
WorkManager的基本用法
先添加依賴
?implementation 'androidx.work:work-runtime-ktx:2.2.0'
WorkManager的基本用法主要分為以下3步:
- 定義一個后臺任務,并實現具體的任務邏輯
- 配置該后臺任務的運行條件和約束信息,并構建后臺任務請求
- 將該后臺任務請求傳入WorkManager的enqueue()方法中,系統會在合適的時間運行
第一步定義一個后臺任務,這里創建一個SimpleWorker類,代碼如下所示:
class SimpleWorker(context: Context,params:WorkerParameters):Worker(context,params) {
override fun doWork(): Result {
Log.d("SimpleWorker", "do Work in SimpleWorker")
return Result.success()//成功就返回Result.success()
}
}
首先每一個后臺任務都必須繼承自Worker類,并調用它唯一的構造函數。然后重寫父類中的doWork()方法,在這個方法中編寫具體的后臺任務邏輯。
第二步配置該后臺任務的運行條件和約束信息
val request = OneTimeWorkRequest.Builder(SimpleWorker::class.java).build()
可以看到,只需要把剛才創建的后臺任務所對應的Class對象傳入 OneTimeWorkRequest.Builder的構造函數當中,然后調用build()方法就可以完成構建。
OneTimeWorkRequest.Builder是WorkRequest.Builder的子類,用于構建單次運行的后臺任務請求。WorkRequest.Builder還有另外一個子類PeriodicWorkRequest.Builder,可用于構建周期性運行的后臺任務請求,但是為了降低設備性能消耗,PeriodicWorkRequest.Builder構造函數中傳入的運行周期間隔不能短于15分鐘,示例代碼如下:
PeriodicWorkRequest.Builder(SimpleWorker::class.java,15,TimeUnit.MINUTES).build()
最后一步,將構建出來的后臺任務請求傳入WorkManager的enqueue()方法中,系統就會在合適的時間去運行
WorkManager.getInstance(this).enqueue(request)
布局增加一個按鈕
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/doWorkBtn" android:layout_gravity="center_horizontal" android:text="Do Work" /> </LinearLayout>
修改MainActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
doWorkBtn.setOnClickListener {
val request = OneTimeWorkRequest.Builder(SimpleWorker::class.java).build()
WorkManager.getInstance(this).enqueue(request)
}
}
}
點擊按鈕后,SimpleWorker打印日志
使用WorkManager處理復雜的任務
首先讓后臺任務在指定的延遲時間后運行,只需要借助setInitialDelay()方法就可以了,代碼如下:
val request = OneTimeWorkRequest.Builder(SimpleWorker::class.java)
.setInitialDelay(5,TimeUnit.MINUTES)
.build()
這就表示我們希望讓SimpleWorker這個后臺任務在5分鐘后運行。
當我們給后臺任務請求添加標簽時,可以這樣寫
val request = OneTimeWorkRequest.Builder(SimpleWorker::class.java)
.addTag("simple")
.build()
添加標簽最主要的一個功能就是通過標簽取消后臺任務請求
WorkManager.getInstance(this).cancelAllWorkByTag("simple")
也可以通過id來取消后臺任務請求:
WorkManager.getInstance(this).cancelWorkById(request.id)
但是使用id只能取消單個后臺任務請求,而使用標簽的話,則可以將同一標簽名的所有后臺任務請求全部取消,這個功能在邏輯復雜的場景尤其有用。
除此之外,還可以使用如下代碼一次性取消所有后臺任務請求:
WorkManager.getInstance(this).cancelAllWork()
如果后臺任務的doWork()方法中返回了Result.retry()那么是可以結合setBackoffCriteria()方法來重新執行任務的,具體代碼如下:
val request = OneTimeWorkRequest.Builder(SimpleWorker::class.java)
.setBackoffCriteria(BackoffPolicy.LINEAR,10,TimeUnit.SECONDS)
.build()
setBackoffCriteria()方法接收3個參數:第二個和第三個參數用于指定在多久之后重新執行任務,時間最短不能少于10秒鐘;第一個參數用于指定如果任務再次執行失敗,下次重試的時間應該以什么樣的形式延遲。第一個參數的可選值有兩種,分別是LINEAR和EXPONENTIAL,前者表示下次重試時間以線性的方式延遲,后者代表下次重試時間以指數的方式延遲。
而doWork()方法中返回的Result.success()和Result.failure()又有什么作用?這兩個返回值其實就是用于通知任務運行結果的,我們可以使用如下代碼進行監聽:
WorkManager.getInstance(this).getWorkInfoByIdLiveData(request.id).
observe(this){
workInfo->
if(workInfo.state==WorkInfo.State.SUCCEEDED){
Log.d(TAG, "do work succeeded")
}else if(workInfo.state==WorkInfo.State.FAILED){
Log.d(TAG, "do work failed")
}
}
這里調用了getWorkInfoByIdLiveData()方法,并傳入后臺任務請求的id,會返回一個LiveData對象。然后我們就可以調用LiveData對象的observe()方法來觀察數據變化了,以監聽后臺任務的運行結果。
另外,還可以調用getWorkInfoByTagLiveData()方法,監聽同一標簽名下所有后臺任務請求的運行結果。
WorkManager還有一個特色的功能—鏈式任務
假設這里定義了3個獨立的后臺任務:同步數據、壓縮數據和上傳數據。現在我們想要實現先同步、再壓縮、最后上傳的功能,就可以借助鏈式任務來實現,代碼示例如下:
val sync=...
val compress=...
val upload=...
WorkManager.getInstance(this)
.beginWith(sync)
.then(compress)
.them(upload)
.enqueue()
beginWith()方法用于開啟一個鏈式任務,至于后面要接上什么樣的后臺任務,只需要使用then()方法來連接即可。另外WorkManager還要求,必須在前一個后臺任務運行成功之后,下一個后臺任務才會運行。也就是說,如果某個后臺任務運行失敗,或者被取消了,那么接下來的后臺任務就得不到運行了。
原文鏈接:https://blog.csdn.net/ChenYiRan123456/article/details/128740405
相關推薦
- 2022-08-26 利用Python實現自動化監控文件夾完成服務部署_python
- 2021-11-03 C++趣味算法之偵探推理_C 語言
- 2022-03-29 詳解python的集合set的函數_python
- 2022-09-23 深入了解C++的多態與虛函數_C 語言
- 2022-05-14 基于Unity編寫一個九宮格抽獎軟件_C#教程
- 2022-02-14 Linux?sftp命令用法_Linux
- 2023-05-31 Pandas提取含有指定字符串的行(完全匹配,部分匹配)_python
- 2022-10-01 Python+OpenCV實現表面缺陷檢測_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支