WorkManager 是 Android Jetpack 提供的一種工具,專門用於處理那些需要延遲執行、即使應用程式關閉或裝置重新啟動也能可靠執行的背景工作。
在你的 app/build.gradle.kts 檔案中添加 WorkManager 的程式庫
dependencies {
// WorkManager dependency
implementation("androidx.work:work-runtime-ktx:2.8.1")
}
範例:
class MyWorker(appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams) {
override fun doWork(): Resul
t {
// 執行工作邏輯
return Result.success()
}
}
實作:
class BlurWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx, params) {
override suspend fun doWork(): Result {
val resourceUri = inputData.getString(KEY_IMAGE_URI)
val blurLevel = inputData.getInt(KEY_BLUR_LEVEL, 1)
return withContext(Dispatchers.IO){
// This is an utility function added to emulate slower work.
delay(DELAY_TIME_MILLIS)
return@withContext try {
require(!resourceUri.isNullOrBlank()) {
val errorMessage =
applicationContext.resources.getString(R.string.invalid_input_uri)
Log.e(TAG, errorMessage)
errorMessage
}
val resolver = applicationContext.contentResolver
val picture = BitmapFactory.decodeStream(
resolver.openInputStream(Uri.parse(resourceUri))
)
val output = blurBitmap(picture, blurLevel)
// Write bitmap to a temp file
val outputUri = writeBitmapToFile(applicationContext, output)
makeStatusNotification(
"Output is $outputUri",
applicationContext
)
val outputData = workDataOf(KEY_IMAGE_URI to outputUri.toString())
//Result.success()
Result.success(outputData)
} catch (throwable: Throwable) {
Log.e(
TAG,
applicationContext.resources.getString(R.string.error_applying_blur),
throwable
)
Result.failure()
}
}
}
}
範例:
val workRequest = OneTimeWorkRequestBuilder<MyWorker>()
.setConstraints(Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build
實作
class WorkManagerBluromaticRepository(context: Context) : BluromaticRepository {
private var imageUri: Uri = context.getImageUri()
private val workManager = WorkManager.getInstance(context)
override val outputWorkInfo: Flow<WorkInfo> =
workManager.getWorkInfosByTagLiveData(TAG_OUTPUT).asFlow().mapNotNull {
if (it.isNotEmpty()) it.first() else null
}
/**
* Create the WorkRequests to apply the blur and save the resulting image
* @param blurLevel The amount to blur the image
*/
override fun applyBlur(blurLevel: Int) {
val blurBuilder = OneTimeWorkRequestBuilder<BlurWorker>()
val constraints = Constraints.Builder()
.setRequiresBatteryNotLow(true)
.build()
blurBuilder.setInputData(createInputDataForWorkRequest(blurLevel, imageUri))
blurBuilder.setConstraints(constraints)
// Add WorkRequest to Cleanup temporary images
var continuation = workManager
.beginUniqueWork(
IMAGE_MANIPULATION_WORK_NAME,
ExistingWorkPolicy.REPLACE,
OneTimeWorkRequest.from(CleanupWorker::class.java)
)
continuation = continuation.then(blurBuilder.build())
val save = OneTimeWorkRequestBuilder<SaveImageToFileWorker>()
.addTag(TAG_OUTPUT)
.build()
continuation = continuation.then(save)
// Start the work
continuation.enqueue()
}
/**
* Cancel any ongoing WorkRequests
* */
override fun cancelWork() {
workManager.cancelUniqueWork(IMAGE_MANIPULATION_WORK_NAME)
}
private fun createInputDataForWorkRequest(blurLevel: Int, imageUri: Uri): Data {
val builder = Data.Builder()
builder.putString(KEY_IMAGE_URI, imageUri.toString()).putInt(KEY_BLUR_LEVEL, blurLevel)
return builder.build()
}
}
範例:
WorkManager.getInstance(context).enqueue(workRequest)
override fun applyBlur(blurLevel: Int) {
// Create WorkRequest to blur the image
val blurBuilder = OneTimeWorkRequestBuilder<BlurWorker>()
// Start the work
workManager.enqueue(blurBuilder.build())
}
https://developer.android.com/courses/pathways/android-basics-compose-unit-7-pathway-1?hl=zh-tw