Android使用Kotlin API實踐WorkManager
WorkManager 提供了一系列 API 可以更加便捷地規(guī)劃異步任務(wù),即使在應(yīng)用被關(guān)閉之后或者設(shè)備重啟之后,仍然需要保證立即執(zhí)行的或者推遲執(zhí)行的任務(wù)被正常處理。對于 Kotlin 開發(fā)者,WorkManager 為協(xié)程提供了最佳的支持。在本文中,我將通過實踐 WorkManager codelab 為大家展示 WorkManager 中與協(xié)程相關(guān)的基本操作。那么讓我們開始吧!
WorkManager 基礎(chǔ)
當(dāng)您需要某個任務(wù)保持運行狀態(tài),即使用戶切換到別的界面或者用戶將應(yīng)用切換到后臺,甚至設(shè)備重啟的時候仍然不影響任務(wù)狀態(tài),那么非常推薦使用 WorkManager。類似的應(yīng)用場景包括:
- 上傳日志或者報告數(shù)據(jù)
- 使用濾鏡處理圖片的同時保存圖片
- 通過網(wǎng)絡(luò)定期同步本地數(shù)據(jù)
如果您的即時任務(wù)可以在用戶脫離某個作用域時結(jié)束,比如切換到其它界面,我們建議您還是直接使用 Kotlin 協(xié)程。
在這個 WorkManager codelab 教程中,我們會對圖片進行模糊化處理,并且將處理后的數(shù)據(jù)存儲在磁盤上。我們看一下這個過程中需要哪些操作。
添加 work-runtime-ktx 依賴:
// 獲取最新的版本號 https://developer.android.google.cn/jetpack/androidx/releases/work def work_version = "2.5.0" implementation "androidx.work:work-runtime-ktx:$work_version"
首先實現(xiàn)我們自己的 Worker 類。我們會在這里實現(xiàn)真正需要在后臺執(zhí)行業(yè)務(wù)的代碼。您可以擴展 Worker 類,并且復(fù)寫 doWork() 方法。由于這個類非常重要,我們會在后邊內(nèi)容中進行詳細介紹。這里是它最初的實現(xiàn)代碼。
/* Copyright 2020 Google LLC.
SPDX-License-Identifier: Apache-2.0 */
class BlurWorker(ctx: Context, params: WorkerParameters) : Worker(ctx, params) {
override fun doWork(): Result {
val resourceUri = inputData.getString(KEY_IMAGE_URI)
return try {
if (resourceUri.isNullOrEmpty()) {
Timber.e("Invalid input uri")
throw IllegalArgumentException("Invalid input uri")
}
val outputData = blurAndWriteImageToFile(resourceUri)
Result.success(outputData)
} catch (throwable: Throwable) {
Timber.e(throwable, "Error applying blur")
Result.failure()
}
}
…
}
接下來,創(chuàng)建我們的 work 請求,在本例中,我們希望整個操作僅運行一次,所以我們使用 OneTimeWorkRequest.Builder,將需要模糊化處理的圖片的 Uri 作為參數(shù)傳入。
Kotlin 小貼士 : 要創(chuàng)建輸入數(shù)據(jù),我們可以使用 workDataOf 函數(shù),它會幫我們創(chuàng)建數(shù)據(jù)構(gòu)建器,并且填充鍵值對,然后為我們創(chuàng)建數(shù)據(jù)。
/* Copyright 2020 Google LLC. SPDX-License-Identifier: Apache-2.0 */ val blurBuilder = OneTimeWorkRequestBuilder<BlurWorker>() val data = workDataOf(KEY_IMAGE_URI to imageUri.toString()) blurBuilder.setInputData(data)
我們使用 WorkManager 類將上面所做的工作添加到計劃隊列并且運行。我們可以提供需要執(zhí)行的任務(wù)和這些任務(wù)的限制條件。
/* Copyright 2020 Google LLC. SPDX-License-Identifier: Apache-2.0 */ val workManager = WorkManager.getInstance(application) val continuation = workManager.beginUniqueWork(blurBuilder.build()) // 執(zhí)行任務(wù) continuation.enqueue()
使 Worker 開始執(zhí)行任務(wù)
當(dāng)您使用 Worker 的時候,WorkManager 會在后臺線程中自動調(diào)用 Worker.doWork()。doWork() 返回的 Result 會告知 WorkManager 服務(wù)是否成功,如果失敗則告知是否需要重試。
Worker.doWork() 屬于同步調(diào)用 -- 您的后臺操作需要以阻塞的方式執(zhí)行,并且所有任務(wù)需要在整個 doWork() 函數(shù)結(jié)束的時候完成。如果您在 doWork() 里調(diào)用異步的 API 然后返回結(jié)果,那么您回調(diào)函數(shù)的執(zhí)行可能會出現(xiàn)問題。
但是如果我希望進行異步操作怎么辦?
我們來將上面的示例操作變得復(fù)雜一點,比如我希望在數(shù)據(jù)庫中存儲所有進行模糊化處理的文件的 Uri。
所以我創(chuàng)建了:
- 一個簡單的 BlurredImage 實體
- 一個用于插入和獲取圖片的 DAO 類
- 數(shù)據(jù)庫
相關(guān)的實現(xiàn)代碼請 點擊這里。
如果您需要執(zhí)行異步操作,比如在數(shù)據(jù)庫中存儲數(shù)據(jù)或者發(fā)起網(wǎng)絡(luò)請求,在 Kotlin 中,我們推薦使用 CoroutineWorker。
CoroutineWorker 通過使用 Kotlin 協(xié)程來執(zhí)行異步任務(wù)。
doWork() 方法是一個 suspend 方法。也就是說我們這里可以調(diào)用可掛起的 dao 函數(shù)。
/* Copyright 2020 Google LLC.
SPDX-License-Identifier: Apache-2.0 */
class BlurWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx, params) {
override suspend fun doWork(): Result {
val resourceUri = inputData.getString(KEY_IMAGE_URI)
return try {
if (resourceUri.isNullOrEmpty()) {
Timber.e("Invalid input uri")
throw IllegalArgumentException("Invalid input uri")
}
val outputData = blurAndWriteImageToFile(resourceUri)
// 將 uri 存儲到數(shù)據(jù)庫
val imageDao = ImagesDatabase.getDatabase(applicationContext).blurredImageDao()
imageDao.insert(BlurredImage(resourceUri))
Result.success(outputData)
} catch (throwable: Throwable) {
Timber.e(throwable, "Error applying blur")
Result.failure()
}
}
...
}
doWork() 默認(rèn)使用 Dispatchers.Default。您可以將其替換為您所需的 Dispatcher。在這里,我們不需要這么做,因為 Room 已經(jīng)將數(shù)據(jù)插入操作放在另外的 Dispatcher 中完成了。更多相關(guān)內(nèi)容可以參考 Room Kotlin API。
開始使用 CoroutineWorker 來執(zhí)行異步任務(wù)吧,即使用戶關(guān)閉應(yīng)用也可以確保任務(wù)完成。
如果您希望了解更多關(guān)于 WorkManager 的內(nèi)容,請關(guān)注未來的相關(guān)文章。在那之前,可以訪問我們的 codelab 和文檔:
以上就是Android使用Kotlin API實踐WorkManager的詳細內(nèi)容,更多關(guān)于Android實踐WorkManager的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android編程添加快捷方式(Short)到手機桌面的方法(含添加,刪除及查詢)
這篇文章主要介紹了Android編程添加快捷方式(Short)到手機桌面的方法,含有針對桌面快捷方式的添加,刪除及查詢的操作實現(xiàn)技巧,需要的朋友可以參考下2016-01-01
Android跨進程傳遞大數(shù)據(jù)的方法實現(xiàn)
這篇文章主要介紹了Android跨進程傳遞大數(shù)據(jù)的方法實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
Android 實現(xiàn)帶進度條的WebView的實例
這篇文章主要介紹了Android 實現(xiàn)帶進度條的WebView的實例的相關(guān)資料,這里介紹了Webview加載網(wǎng)頁的方法及帶進度的Drawable文件view_progress_webview的實現(xiàn),需要的朋友可以參考下2017-07-07
Android調(diào)用系統(tǒng)拍照裁剪圖片模糊的解決方法
這篇文章主要為大家詳細介紹了Android調(diào)用系統(tǒng)拍照裁剪圖片模糊的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01
Android?Studio實現(xiàn)簡單頁面跳轉(zhuǎn)的詳細教程
這篇文章主要給大家介紹了關(guān)于Android?Studio實現(xiàn)簡單頁面跳轉(zhuǎn)的詳細教程,文中通過圖文介紹的非常詳細,對大家學(xué)習(xí)或者使用Android?Studio具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2023-01-01

