安卓WorkManager

WorkManagerAndroid Jetpack 提供的一个 API,也是是一种架构组件,用于执行后台任务。它特别适合那些需要 保证一定会执行
的任务,即使应用被杀掉、设备重启,任务也会在合适的时候继续执行。

可以简单理解为:
WorkManager
适合处理那些执行时间比用户在当前界面停留时间更长的任务,甚至应用退出/被杀后也要继续完成的任务。


WorkManager 的特点

  • 可靠性高:任务会保存到数据库,应用被杀/重启后也会执行
  • 支持约束条件:如仅在联网/充电/空闲时执行
  • 支持一次性和周期性任务
  • 支持链式任务(先后依赖关系)

适用场景

  • 必须保证执行的后台任务:日志上传、数据备份、数据同步
  • 需要满足特定条件才执行的任务:仅在 WiFi 下上传大文件
  • 可延迟执行,但最终必须完成的任务:定时推送、缓存清理

不适用的场景:

  • ⛔ 实时任务(即时消息) → 用 ServiceForegroundService
  • ⛔ 短时间后台任务(几秒内) → 用 Coroutine + LifecycleScope

WorkManager 的三大核心组件

1. Worker

Worker 是一个在后台线程上同步执行工作的类。因为我们需要的是异步工作,所以可以使用 CoroutineWorker,它可与 Kotlin 协程进行互操作。定义具体任务逻辑,继承 WorkerCoroutineWorker,重写 doWork()

Worker示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//定义一个日志标签,方便后面用 Log.e 打印日志时标识来源。
private const val TAG = "BlurWorker"

class BlurWorker(ctx: Context, params: WorkerParameters): CoroutineWorker(ctx,params){
// 用 @RequiresPermission 注解,表示调用此方法需要有通知权限(Android 13+)
@RequiresPermission(Manifest.permission.POST_NOTIFICATIONS)
// 重写 doWork 方法,这是 WorkManager 的核心方法,用于执行后台任务。
override suspend fun doWork(): Result {
// 从 inputData 里读取图片的 Uri 和模糊等级,支持动态处理不同图片和不同模糊程度。
val resourceUri = inputData.getString(KEY_IMAGE_URI)
val blurLevel = inputData.getInt(KEY_BLUR_LEVEL, 1)
// 显示一条“正在处理图片”的通知,告诉用户后台任务已经开始。
makeStatusNotification(
// applicationContext 是 CoroutineWorker 提供的全局 Context。
applicationContext.resources.getString(R.string.blurring_image),
applicationContext
)
// 切换到 IO 线程执行耗时操作
return withContext(Dispatchers.IO){
//return try {
return@withContext try{
//人为延迟一段时间,模拟任务耗时
delay(DELAY_TIME_MILLIS)
require(! resourceUri.isNullOrBlank()){
val errorMessage = applicationContext.resources.getString(R.string.invalid_input_uri)
Log.e(TAG, errorMessage)
errorMessage
}
// 现在通过 ContentResolver 和传入的 Uri 加载图片
val resolver = applicationContext.contentResolver
val picture = BitmapFactory.decodeStream(
resolver.openInputStream(Uri.parse(resourceUri))
)
// 调用 blurBitmap 方法,对图片进行模糊处理
val output = blurBitmap(picture, blurLevel)
// 调用 writeBitmapToFile 方法,将模糊后的图片保存到文件中。
val outputUri = writeBitmapToFile(applicationContext, output)
// 创建一个包含输出 Uri 的 Data 对象,用于传递给下一个任务。
val outputData = workDataOf(KEY_IMAGE_URI to outputUri.toString())
// 把处理后的图片 Uri 作为输出数据返回
Result.success(outputData)
} catch (throwable: Throwable) {
Log.e(
TAG,
applicationContext.resources.getString(R.string.error_applying_blur),
throwable
)
Result.failure()
}
}
}
}
  • 返回值:
    • Result.success() → 成功
    • Result.failure() → 失败,不再重试
    • Result.retry() → 请求系统重试

2. WorkRequest

此类表示请求执行某些工作。WorkRequest 用于定义 worker 是需要运行一次还是定期运行。也可以对 WorkRequest 设置约束条件,要求在运行工作之前满足特定条件。例如,设备在开始请求的工作之前在充电状态。只需要用 WorkManager 的 enqueue 方法提交 WorkRequest,剩下的 Worker 调用和任务调度,系统会自动完成。

描述任务的调度方式:

  • OneTimeWorkRequest:一次性任务\
  • PeriodicWorkRequest:周期性任务(最小间隔 15 分钟)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class WorkManagerBluromaticRepository(context: Context) : BluromaticRepository {
// 通过 context.getImageUri() 获取了一个图片的 Ur
private var imageUri: Uri = context.getImageUri()
private val workManager = WorkManager.getInstance(context)
override val outputWorkInfo: Flow<WorkInfo?> = MutableStateFlow(null)

// 实现接口 BluromaticRepository 的方法,用于发起“模糊图片”的后台任务。
override fun applyBlur(blurLevel: Int) {
// 创建一个只执行一次的 WorkRequest,指定任务是 BlurWorker
val blurBuilder = OneTimeWorkRequestBuilder<BlurWorker>()
// 通过 setInputData 方法,把图片的 Uri 和模糊等级一起传递给 BlurWorker
blurBuilder.setInputData(createInputDataForWorkRequest(blurLevel,imageUri))
// 把这个任务加入 WorkManager 队列,系统会自动调度执行。
workManager.enqueue(blurBuilder.build())

}

override fun cancelWork() {}

/**
* Creates the input data bundle which includes the blur level to
* update the amount of blur to be applied and the Uri to operate on
* @return Data which contains the Image Uri as a String and blur level as an Integer
*/
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()
}
}

3. WorkManager

此类实际上会调度 WorkRequest 并使其运行。它以一种在系统资源上分散负载的方式调度 WorkRequest,同时遵循你指定的约束条件。 是系统提供的任务调度器,负责执行、管理和监控任务。

1
2
3
4
5
6
7
8
9
10
11
// 调度任务
WorkManager.getInstance(context).enqueue(oneTimeWorkRequest)

// 观察任务状态
WorkManager.getInstance(context)
.getWorkInfoByIdLiveData(oneTimeWorkRequest.id)
.observe(lifecycleOwner) { workInfo ->
if (workInfo != null && workInfo.state == WorkInfo.State.SUCCEEDED) {
// 任务完成
}
}

三者关系总结

  • Worker:定义任务 → 干什么?
  • WorkRequest:配置任务 → 什么时候执行?执行条件?
  • WorkManager:调度任务 → 怎么执行?执行状态如何?

总结

  • WorkManager = 后台任务调度器,适合延时、保证执行的任务
  • 不适合实时或短时任务\
  • 核心思路:Worker (任务) + WorkRequest (调度条件) + WorkManager
    (执行管理)
  • Copyrights © 2023-2025 Hexo

请我喝杯咖啡吧~

支付宝
微信