WorkManager使用入門
WorkManager
提供了任務排程功能,我們可以對工作進行標記或命名。
我們用一個示例來演示如何使用WorkManager。本文使用Kotlin。
入門示例
gradle引入依賴
將以下依賴項新增到應用模組的build.gradle檔案中
dependencies {
def work_version = "2.5.0"
// (Java only)
implementation "androidx.work:work-runtime:$work_version"
// Kotlin + coroutines
implementation "androidx.work:work-runtime-ktx:$work_version"
// optional - RxJava2 support
implementation "androidx.work:work-rxjava2:$work_version"
// optional - GCMNetworkManager support
implementation "androidx.work:work-gcm:$work_version"
// optional - Test helpers
androidTestImplementation "androidx.work:work-testing:$work_version"
// optional - Multiprocess support
implementation "androidx.work:work-multiprocess:$work_version"
}
新增依賴項並同步 Gradle 後,下一步要定義一些工作。
定義工作
這裡的工作為方便測試進行了簡化。實際專案中請改為具體的業務程式碼。
新建UploadWorker
類繼承Worker
類。需要2個引數context: Context, params: WorkerParameters
。
在doWork()
方法中是我們的具體任務,在WorkManager
提供的後臺執行緒上非同步執行。
class UploadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
for (i in 1..3) {
Log.d(TAG, "模擬執行任務 ${tags.first()} ${Thread.currentThread()}")
Thread.sleep(100) // 模擬耗時
}
return Result.success()
}
}
doWork()
方法中我們列印當前執行緒資訊。後面看看執行緒執行情況。
任務執行完畢,doWork()
需要返回一個Result
:
Result.success()
:工作成功完成Result.failure()
:工作失敗Result.retry()
:工作失敗,應根據其重試政策在其他時間嘗試
建立 WorkRequest
前面我們定義好了工作類UploadWorker
。WorkManager
可以排程工作,讓工作執行起來。工作可以在某個時間段內定期執行,也可以只執行一次。
要執行工作,涉及到WorkRequest
類和它的子類。
這裡我們演示只執行1次的工作,使用OneTimeWorkRequest
。
建立workA
,作為一個Activity裡的變數
private val mWorkA = OneTimeWorkRequest.Builder(UploadWorker::class.java)
.addTag("workA").build()
建立workB
val workB = OneTimeWorkRequest.Builder(UploadWorker::class.java)
.addTag("workB").build()
將WorkRequest提交給WorkManager
使用enqueue
方法將WorkRequest提交給WorkManager。
獲取WorkManager
的例項用WorkManager.getInstance(applicationContext)
方法。
mWorkA
是變數
WorkManager.getInstance(applicationContext).enqueue(mWorkA)
// ...
workB
是每次都新建一個物件,然後交給WorkManager
去執行。
val workB = OneTimeWorkRequest.Builder(UploadWorker::class.java)
.addTag("workB").build()
WorkManager.getInstance(applicationContext).enqueue(workB)
執行工作器的確切時間取決於WorkRequest
中使用的約束和系統優化方式。
Google官方設計過WorkManager
,能夠在滿足約束的情況下提供最佳行為。
執行測試
按鈕A觸發mWorkA
,按鈕B觸發workB
。分別點選按鈕A/B
模擬執行任務 workA Thread[pool-2-thread-3,5,main]
模擬執行任務 workA Thread[pool-2-thread-3,5,main]
模擬執行任務 workA Thread[pool-2-thread-3,5,main]
點選按鈕B Thread[main,5,main]
模擬執行任務 workB Thread[pool-2-thread-1,5,main]
模擬執行任務 workB Thread[pool-2-thread-1,5,main]
模擬執行任務 workB Thread[pool-2-thread-1,5,main]
觀察log發現,工作的doWork()
方法在WorkManager
提供的後臺執行緒上非同步執行。
主執行緒是[main,5,main]
,工作的執行緒是[pool-2-thread-3,5,main]
。
而在實際操作中發現,多次點選按鈕A,mWorkA
只會執行第一次。後面再點選按鈕A,mWorkA
也不會執行了。
小結
這個例子介紹瞭如何引入WorkManager
,定義工作(任務),排隊執行任務。
在使用方式上,讓人聯想到AsyncTask。
其他參考
- Google 使用WorkManager排程任務 https://developer.android.com/topic/libraries/architecture/workmanager
- WorkManager使用入門 https://developer.android.com/topic/libraries/architecture/workmanager/basics