官網連結 使用 WorkManager 排程任務 | Android 開發者 | Android Developers
https://developer.android.google.cn/topic/libraries/architecture/workmanager
WorkManager 是一個 API,可供您輕松排程那些即使在退出應用或重新開機裝置後仍應運作的可靠異步任務。
WorkManager 适用于需要可靠運作的工作,即使使用者導航離開螢幕、退出應用或重新開機裝置也不影響工作的執行。例如:
- 向後端服務發送日志或分析資料
- 定期将應用資料與伺服器同步
簡言之,WorkManager 用于執行背景任務。
優勢:
- 使用工作限制明确定義工作運作的最佳條件。工作限制有電量充足、聯網限制(如僅Wifi情況)、裝置空閑等。
- 排程靈活。可以執行一次或周期性任務,可對任務添加标記,可取消任務。
- 靈活的重試政策。任務執行失敗的話可選擇重試。
- 工作鍊。對于多個任務,可以約定任務的先後執行關系。
開始使用,
1.添加依賴
dependencies {
def work_version = "2.5.0"
// WorkManager
implementation "androidx.work:work-runtime:$work_version"
}
2.自定義Worker
自定義一個任務,繼承 Worker ,重寫 doWork() 方法,doWork() 方法中實作具體的背景任務邏輯。
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
class MyWorker(context: Context, parameters: WorkerParameters) : Worker(context, parameters) {
override fun doWork(): Result {
//TODO("Not yet implemented")
// do really work
return Result.success()
}
}
doWork() 傳回的 Result 結果有:
- Result.success():工作成功完成。
- Result.failure():工作失敗。
- Result.retry():工作失敗,可根據配置的重試政策在其他時段重試。
3.建立請求 WorkRequest
使用 OneTimeWorkRequest 建立單次運作的背景任務請求,
var request = OneTimeWorkRequest.Builder(MyWorker::class.java).build()
可以添加 标簽和 其他限制條件,
var request = OneTimeWorkRequest
.Builder(MyWorker::class.java)
//10分鐘後執行
.setInitialDelay(10, TimeUnit.MINUTES)
// 标簽設為 tag_request ,可根據标簽取消任務
.addTag("tag_request")
// 結合 Result.retry() 使用,任務失敗重新執行任務,
//任務實行失敗的話, 60 秒後重試,再次失敗的話,下次重試的時間間隔線性增加(也可以設定成指數性(BackoffPolicy.EXPONENTIAL)增加)
.setBackoffCriteria(BackoffPolicy.LINEAR, 60, TimeUnit.SECONDS)
.build()
如果設定了 setBackoffCriteria ,可以根據任務的 id 來監聽任務執行結果,
WorkManager.getInstance(this).getWorkInfoByIdLiveData(request.id)
.observe(this){ workInfo ->
if (workInfo.state == WorkInfo.State.SUCCEEDED) {
} else if (workInfo.state == WorkInfo.State.FAILED) {
}
}
4.将 WorkRequest 送出給系統
很簡單,這樣就送出給系統了,系統會在合适的時機執行。
WorkManager.getInstance(this).enqueue(request)
5.工作鍊
有多個任務的話,可以限制他們的先後執行關系,
val request1 = OneTimeWorkRequest.Builder(MyWorker::class.java).addTag("request1").build()
val request2 = OneTimeWorkRequest.Builder(MyWorker::class.java).addTag("request2").build()
val request3 = OneTimeWorkRequest.Builder(MyWorker::class.java).addTag("request3").build()
WorkManager.getInstance(this)
.beginWith(request1)
.then(request2)
.then(request3)
.enqueue()
先執行 request1 ,再執行 request2 ,然後執行 request3 。如果 request1 執行失敗,request2 和 request3 就不會執行。
6.取消任務
根據 id 取消單個任務
WorkManager.getInstance(this).cancelWorkById(request.id)
根據 tag 取消此 tag 下的所有任務
WorkManager.getInstance(this).cancelAllWorkByTag("tag_request")
取消所有任務
WorkManager.getInstance(this).cancelAllWork()