Jetpack WorkManager 是 Android 推荐的后台任务调度库,用于处理延迟任务、周期性任务及需保证执行的任务(即使应用退出或设备重启)。本文会从核心概念、使用示例、适用场景、注意事项到版本兼容性进行全面解析。
一、核心概念
1. Worker
任务执行单元,需继承 CoroutineWorker
(协程)或 Worker
(同步),重写 doWork()
方法。
2. WorkRequest
定义任务的触发条件(如网络状态、充电状态)、约束、重试策略等,分两种类型:
OneTimeWorkRequest
:一次性任务。PeriodicWorkRequest
:周期性任务(间隔 ≥15分钟)。
3. WorkManager
任务调度器,负责将 WorkRequest
加入队列并管理执行。
4. WorkInfo
任务状态(ENQUEUED
、RUNNING
、SUCCEEDED
、FAILED
、CANCELLED
)。
二、使用示例
1. 基础配置
-
添加依赖:
gradle// build.gradle (app) dependencies { implementation "androidx.work:work-runtime-ktx:2.9.0" // 可选:测试支持 androidTestImplementation "androidx.work:work-testing:2.9.0" }
2. 定义 Worker
kotlin
class UploadWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
// 获取输入数据
val data = inputData.getString("KEY_FILE_URI") ?: return Result.failure()
return try {
// 执行上传逻辑(模拟耗时)
uploadFileToServer(data)
Result.success(workDataOf("KEY_RESULT" to "Success"))
} catch (e: Exception) {
Result.retry() // 或 Result.failure()
}
}
private suspend fun uploadFileToServer(uri: String) {
delay(5000) // 模拟上传
}
}
3. 创建 WorkRequest 并提交
kotlin
// 定义约束:网络连接且设备充电时执行
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(true)
.build()
// 创建输入数据
val inputData = workDataOf("KEY_FILE_URI" to "content://file_path")
// 构建一次性请求
val uploadRequest = OneTimeWorkRequestBuilder<UploadWorker>()
.setInputData(inputData)
.setConstraints(constraints)
.setBackoffCriteria(BackoffPolicy.LINEAR, 10, TimeUnit.SECONDS) // 重试策略
.build()
// 提交任务
WorkManager.getInstance(context).enqueue(uploadRequest)
4. 观察任务状态
kotlin
WorkManager.getInstance(context)
.getWorkInfoByIdLiveData(uploadRequest.id)
.observe(this) { workInfo ->
when (workInfo?.state) {
WorkInfo.State.SUCCEEDED -> {
val result = workInfo.outputData.getString("KEY_RESULT")
Toast.makeText(context, "上传成功:$result", Toast.LENGTH_SHORT).show()
}
WorkInfo.State.FAILED -> { /* 处理失败 */ }
WorkInfo.State.CANCELLED -> { /* 处理取消 */ }
else -> { /* 其他状态 */ }
}
}
5. 周期性任务
kotlin
val dailyRequest = PeriodicWorkRequestBuilder<SyncWorker>(
1, TimeUnit.DAYS, // 间隔周期
15, TimeUnit.MINUTES // 灵活间隔(实际间隔为周期+灵活间隔)
).build()
WorkManager.getInstance(context).enqueue(dailyRequest)
三、适用场景
1. 需保证执行的任务
- 日志上传、数据同步(即使应用关闭或设备重启)。
2. 延迟任务
- 用户退出界面后提交反馈、缓存清理。
3. 条件触发任务
- 仅在充电时备份数据、有网络时下载文件。
4. 任务链与依赖
-
顺序执行:压缩文件 → 上传 → 发送通知。
kotlinWorkManager.getInstance(context) .beginWith(compressWorkRequest) .then(uploadWorkRequest) .then(notifyWorkRequest) .enqueue()
四、注意事项
1. 任务执行时间限制
- 普通 Worker:默认约10分钟(Android 12+ 限制为10分钟)。
- 长时任务 :使用
ForegroundService
替代。
2. 避免任务冲突
- 使用
UniqueWorkPolicy
(REPLACE
、KEEP
、APPEND
)管理唯一任务。
3. 输入输出数据限制
- 数据大小不超过 10KB (使用
Data
类序列化)。
4. 测试与调试
-
使用
WorkManagerTestInitHelper
模拟任务执行。kotlin@RunWith(AndroidJUnit4::class) class UploadWorkerTest { @Test fun testUploadWorker() = runTest { val request = OneTimeWorkRequestBuilder<UploadWorker>().build() val testDriver = WorkManagerTestInitHelper.getTestDriver(context) WorkManager.getInstance(context).enqueue(request).result.get() testDriver?.setAllConstraintsMet(request.id) // 触发约束条件 val workInfo = WorkManager.getInstance(context).getWorkInfoById(request.id).get() assertThat(workInfo.state).isEqualTo(WorkInfo.State.SUCCEEDED) } }
五、版本兼容性
Android 版本 | WorkManager 行为 |
---|---|
API ≥ 23 (Android 6.0+) | 使用 JobScheduler (系统级调度,低功耗)。 |
API 21-22 | 使用 JobScheduler 和 AlarmManager 组合。 |
API ≤ 20 | 使用 AlarmManager 和 BroadcastReceiver 。 |
所有版本 | 任务持久化存储(设备重启后自动重新调度)。 |
-
最低支持:API 14(Android 4.0)。
-
ProGuard 规则 :保留 Worker 类。
proguard-keep class * extends androidx.work.Worker -keep class * extends androidx.work.CoroutineWorker
六、与 Hilt 集成(依赖注入)
一文带你了解 Android 中 Dagger/Hilt 的原理和简单使用
kotlin
@HiltWorker
class AnalyticsWorker @AssistedInject constructor(
@Assisted context: Context,
@Assisted params: WorkerParameters,
private val analyticsService: AnalyticsService // 注入依赖
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
analyticsService.logEvent("worker_started")
return Result.success()
}
}
七、总结
- 优势:统一后台任务调度、支持复杂约束、自动兼容不同 API 版本。
- 推荐场景:数据同步、日志上传、条件触发的后台任务。
- 最佳实践 :
- 短时任务使用
CoroutineWorker
。 - 长时任务改用前台服务。
- 合理设置
Constraints
和BackoffCriteria
。 - 使用
WorkManagerTestInitHelper
进行单元测试。
- 短时任务使用
通过 WorkManager,开发者可高效管理后台任务,确保用户体验与设备性能的平衡。