簡介
WorkManager適合處理一些定時執行的任務,它可以根據操作系統的版本自動選擇底層是使用AlarmManager實現還是JobScheduler,降低我們的使用成本,同時他還支持週期性任務、鏈式任務處理等功能。
WorkManager可以在應用退出或者手機重啓的情況下,還能夠執行之前註冊的任務
主要功能
添加網絡可用性或充電狀態等工作約束
調度一次性或週期性異步任務
監控和管理計劃任務
將任務鏈接起來
確保任務執行,即使應用或設備重啓也同樣執行任務
遵循低電耗模式等省電功能
使用
在build.gradle中引入依賴
dependencies {
...
implementation 'androidx.work:work-runtime:2.3.0'
}
創建WorkManager後臺任務
class WorkManagerTest(context: Context, workerParams: WorkerParameters) : Worker(
context,
workerParams
) {
// 該方法在WorkManager提供的後臺線程上同步運行
override fun doWork(): Result {
Log.e("WorkManagerTest", "do work in workmanager")
// 返回結果表示任務運行結果,
return Result.success()
}
}
配置約束條件並調用後臺任務
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
doWork.setOnClickListener {
// 構建單次運行的後臺任務請求
val request = OneTimeWorkRequest.Builder(WorkManagerTest::class.java).build()
// 構建週期性運行的後臺任務請求, 爲了降低設備的性能功耗,運行週期間隔不得少於15分鐘
val request1 =
PeriodicWorkRequest.Builder(WorkManagerTest::class.java, 15, TimeUnit.MINUTES)
.build()
// 系統在合適的時間調用兩個後臺任務
WorkManager.getInstance(this).enqueue(request)
WorkManager.getInstance(this).enqueue(request1)
}
}
}
高級特性
1. 創建後臺任務請求時建立約束
val request = OneTimeWorkRequest.Builder(WorkManagerTest::class.java)
.setInitialDelay(5, TimeUnit.MINUTES) // 讓任務在指定延時後執行
.addTag("test") // 添加請求標籤,並可以通過WorkManager.getInstance(this).cancelAllWorkByTag("test") 取消任務
.setBackoffCriteria(
BackoffPolicy.LINEAR,
10,
TimeUnit.SECONDS
) // 如果任務返回result.retry(), 可以通過該函數進行重試,第一個參數表示再次失敗後延遲執行的形式,LINEAR表示線性延遲, EXPONENTIAL表示指數方式延遲,第二第三個參數表示指定在多久之後重新執行任務,不得少於10秒
.build()
2. 監聽後臺任務的狀態變化
// 監聽後臺任務的狀態變化
WorkManager.getInstance(this).getWorkInfoByIdLiveData(request.id)
.observe(this, Observer { workInfo ->
if (workInfo.state == WorkInfo.State.SUCCEEDED) {
Log.e("MainActivity", "Work Successed")
} else if (workInfo.state == WorkInfo.State.FAILED) {
Log.e("MainActivity", "Work Failed")
}
})
3. 任務的鏈式調用
// WorkManager鏈式調用
WorkManager.getInstance(this)
// Candidates to run in parallel
.beginWith(download)
// Dependent work (only runs after all previous work in chain)
.then(compress)
.then(upload)
// Don't forget to enqueue()
.enqueue()
4. 取消任務
// 通過id取消任務
WorkManager.getInstance(this).cancelWorkById(request.id)
// 通過tag取消任務
WorkManager.getInstance(this).cancelAllWorkByTag("test")