WorkManager — 是一个Android Jetpack库,用于执行延迟和后台任务,并提供执行保证。与Service或JobScheduler不同,WorkManager负责管理任务的生命周期:在失败时重新启动,适应Android版本,并考虑设备的限制。根据Android Developers, 2026,WorkManager是现代Android开发中大多数后台操作的首选解决方案。
要点
WorkManager — 是Android Jetpack的一部分,是一个用于管理后台任务的库,这些任务必须保证执行,无论应用程序是在前台还是被用户关闭。该库支持API 14+,并自动选择合适的执行机制:Android 5+上的JobScheduler,旧版本上的BroadcastReceiver + AlarmManager。
WorkManager的关键特性是执行保证。如果任务由于设备重启、应用程序停止或故障而未完成,WorkManager将在第一时间重新启动它。这使得该库成为对执行至关重要的任务的理想选择:发送分析数据、数据库同步、上传日志。
与Background Service不同,WorkManager不需要线程和生命周期管理。该库自行创建线程池,处理Doze Mode,考虑Android版本,并提供统一的API,与API级别无关。通过CoroutineWorker和RxWorker分别支持与协程和RxJava一起工作。
WorkManager提供对LiveData的内置支持,用于跟踪任务状态。getWorkInfoByIdLiveData方法返回LiveData<WorkInfo>,它在每次状态更改时更新:ENQUEUED、RUNNING、SUCCEEDED、FAILED、CANCELLED。这允许UI组件响应更改,而无需手动轮询调度程序,并且由于Lifecycle-aware组件而不会发生内存泄漏。
WorkManager.getInstance(context)
.getWorkInfoByIdLiveData(syncRequest.id)
.observe(viewLifecycleOwner) { workInfo ->
when (workInfo.state) {
WorkInfo.State.SUCCEEDED ->
showSuccess()
WorkInfo.State.FAILED ->
showError(workInfo.outputData)
else ->
showProgress()
}
}
WorkManager的架构围绕三个基本类构建:Worker、WorkRequest和WorkManager。Worker包含任务逻辑,WorkRequest描述执行参数,WorkManager管理队列和计划。该库使用内部Room数据库来存储所有任务的状态。
Worker — 是一个抽象类,只有一个方法doWork,在后台线程中调用。该方法返回ListenableWorker.Result — SUCCESS、FAILURE或RETRY。WorkRequest将Worker与参数关联:超时、标签、初始延迟和约束条件。
class SyncWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun doWork(): Result {
return try {
val api = RetrofitClient.api
val response = api.syncData()
Result.success()
} catch (e: Exception) {
Result.retry()
}
}
}
WorkManager统一计划任务,与Android版本无关。调用enqueue时,库将任务保存在Room中,评估当前条件,并选择最佳启动时间。在底层,可以使用JobScheduler、AlarmManager或自己的调度程序——开发人员无需关心这些。
val syncRequest = OneTimeWorkRequestBuilder<SyncWorker>()
.setInitialDelay(15, TimeUnit.MINUTES)
.addTag("sync")
.build()
WorkManager.getInstance(context)
.enqueue(syncRequest)
WorkManager支持两种类型的执行请求:单次和周期性。类型的选择取决于场景:任务应该执行一次还是以特定间隔重复执行。
OneTimeWorkRequest用于应执行一次的任务。这可以是发送日志、授权后的数据同步、首次启动时的配置加载。延迟通过setInitialDelay设置,约束条件通过setConstraints设置。
PeriodicWorkRequest适用于重复性任务,最小间隔为15分钟。该库保证执行之间的间隔不会小于指定的间隔,但由于设备限制可能会更长。对于频率低于15分钟的任务,请使用Foreground Service中的Handler或Timer。
| 参数 | OneTimeWorkRequest | PeriodicWorkRequest |
|---|---|---|
| 频率 | 单次 | 重复(最小15分钟) |
| 次数 | 1次执行 | 直到取消 |
| 延迟 | setInitialDelay | setInitialDelay |
| 链 | 支持 | 不支持 |
| 用途 | 加载、同步 | 监控、轮询 |
WorkManager中的约束条件(constraints)允许设置任务启动的条件:网络连接(NetworkType)、电池电量(batteryNotLow)、存储状态(StorageNotLow)和空闲模式(DeviceIdle)。在满足所有约束条件之前,任务不会启动。
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(true)
.setRequiresBatteryNotLow(true)
.build()
val request = OneTimeWorkRequestBuilder<ImageUploadWorker>()
.setConstraints(constraints)
.build()
链(chaining)允许组织任务的顺序或并行执行。beginWith启动一个链,then添加下一个Worker,它将在前一个成功完成后执行。对于并行执行,使用workManager.enqueue(listOf(request1, request2))。
WorkManager.getInstance(context)
.beginWith(compressWorker)
.then(uploadWorker)
.then(cleanupWorker)
.enqueue()
// compress -> upload -> cleanup 顺序执行
JobScheduler在Android 5(API 21)中被引入,作为计划后台任务的系统服务。WorkManager作为替代品出现,提供跨平台API、自动迁移和额外功能:链、执行保证、标签、通过LiveData进行状态监控。
在从JobScheduler迁移到WorkManager时,需要将JobService转换为Worker,将JobInfo替换为WorkRequest,将Context.getSystemService替换为WorkManager API。WorkManager自动解决兼容性问题,并比手动实现JobScheduler更正确地处理Doze Mode。迁移步骤:1)创建Worker类,2)使用相同条件构建WorkRequest,3)从代码和清单中删除JobService和JobInfo。
WorkManager通过ExistingWorkPolicy支持唯一任务的概念。如果具有指定名称的任务已存在,策略决定行为:KEEP(不创建新任务)、REPLACE(替换现有任务)、APPEND(添加到链的末尾)和APPEND_OR_REPLACE。UniqueWorkRequest适用于不应重复的任务:数据库同步、配置加载、发送分析数据包。
WorkManager.getInstance(context)
.enqueueUniqueWork(
"sync_data",
ExistingWorkPolicy.KEEP,
syncRequest
)
CoroutineWorker支持setProgress机制,允许传递任务的中间结果。这对于长时间操作很有用:加载大文件、批量处理图像、数据库迁移。UI可以通过getWorkInfosByTagLiveData订阅更新,并实时显示进度。还可以使用ForegroundInfo方法将Worker作为带有通知的Foreground Service启动,如果任务需要对用户可见的话。
class ProgressWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
val total = 100
for (i in 1..total) {
setProgress(
workDataOf("progress" to i)
)
}
return Result.success()
}
}
WorkManager支持通过InputData和OutputData在Worker之间传输数据。InputData在构建WorkRequest时通过Data.Builder创建,并通过inputData传递给Worker。执行后,Worker通过workDataOf或Data.Builder创建OutputData,并与Result.success(outputData)一起返回。链中的下一个Worker接收前一个的输出数据作为其输入数据。数据以键值格式存储,支持基本类型:String、Int、Long、Boolean、Double。Data的最大大小为10 KB。
在实践中,许多项目使用WorkManager作为唯一的后台任务调度程序。Google建议将所有现有的JobService迁移到WorkManager,特别是在支持Android 4.4(API 19)及更低版本的应用程序中,这些版本中JobScheduler不可用,而WorkManager通过AlarmManager和BroadcastReceiver使用备用机制。对于测试,WorkManager提供了TestListenableWorkerBuilder和TestWorkerBuilder,允许在JUnit测试中测试Worker,而无需实际的调度程序。
要测试WorkManager,请使用AndroidX Test中的TestListenableWorkerBuilder,它允许在隔离环境中运行Worker并检查返回的Result。该库提供对JUnit和Robolectric的完全支持,用于无需实际调度程序的模块化测试。总的来说,WorkManager适用于80%以前使用Service或JobScheduler的任务。
常见问题
是的,WorkManager保证即使在重启后也能执行。该库将所有未完成的任务保存在Room数据库中,并通过系统启动后触发的BroadcastReceiver恢复它们。
Worker在后台线程中工作,不支持协程或RxJava。CoroutineWorker使用Kotlin协程,支持suspend函数和通过协程作用域取消。RxWorker与Observable和Single一起工作,适用于响应式链。
取消时,使用workManager.cancelWorkById(id)或workManager.cancelAllWorkByTag(“tag”)。该库还提供cancelUniqueWork(“name”)方法用于取消具有指定名称的唯一任务。
PeriodicWorkRequest的最小间隔是15分钟。此限制由Google设置,以防止过度消耗电池。如果任务需要更频繁地执行,请使用Foreground Service或带有定时器的Handler。
是的,WorkManager支持API 14+。在没有JobScheduler(低于API 21)的设备上,该库使用AlarmManager和BroadcastReceiver的组合来计划任务。这使得WorkManager成为后台任务的通用解决方案。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。