WorkManager 与后台任务
使用 WorkManager 安排有保障的后台工作。使用 OneTimeWorkRequest、PeriodicWorkRequest、约束、数据传递和工作链。
WorkManager 与后台任务 是 CoddyKit 上的免费 Android Academy 课时。 这是第 5 节课,共 6 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Android Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Android Academy 课程共包含 6 节课。
Android 中的后台任务
Android 会严格限制后台任务,以节省电量。在 WorkManager 出现之前,开发者使用过:
- AsyncTask(已弃用)
- AlarmManager(在设备重启或进入 Doze 模式后不可靠)
- JobScheduler(API 复杂)
- 服务(可能被终止,且不支持重试)
WorkManager 是处理可延迟且必须执行的后台任务的推荐方案。
什么是 WorkManager?
WorkManager 可以确保任务运行,即使应用被终止或设备重启也不例外。它可以:
- 在设备重启后保留任务
- 失败时自动重试
- 支持约束条件(仅使用 WiFi、仅在充电时运行等)
- 支持 API 14+
- 通过
CoroutineWorker与 Kotlin 协程集成
设置
将 WorkManager 添加到 app/build.gradle:
dependencies {
implementation 'androidx.work:work-runtime-ktx:2.9.0'
}创建 Worker
继承 CoroutineWorker 并实现 doWork()。返回 Result.success()、Result.failure() 或 Result.retry():
class SyncWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
return try {
// This runs on a background coroutine
val repo = UserRepository(applicationContext)
repo.syncFromNetwork()
Result.success()
} catch (e: Exception) {
if (runAttemptCount < 3) Result.retry()
else Result.failure()
}
}
}OneTimeWorkRequest
安排一次性任务并将其加入队列:
val syncWork = OneTimeWorkRequestBuilder<SyncWorker>()
.setInitialDelay(10, TimeUnit.MINUTES) // optional delay
.build()
WorkManager.getInstance(context).enqueue(syncWork)
// With a unique name (prevents duplicates):
WorkManager.getInstance(context).enqueueUniqueWork(
"sync_work",
ExistingWorkPolicy.KEEP, // don't enqueue if already pending
syncWork
)PeriodicWorkRequest
安排重复任务。最短间隔为 15 分钟:
val periodicSync = PeriodicWorkRequestBuilder<SyncWorker>(
repeatInterval = 1, TimeUnit.HOURS
).build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
"hourly_sync",
ExistingPeriodicWorkPolicy.KEEP,
periodicSync
)约束条件
仅在满足条件时运行任务,例如电量不低、已连接 WiFi 等:
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED) // WiFi only
.setRequiresBatteryNotLow(true)
.setRequiresCharging(false)
.build()
val work = OneTimeWorkRequestBuilder<SyncWorker>()
.setConstraints(constraints)
.build()
WorkManager.getInstance(context).enqueue(work)输入与输出数据
使用 Data 对象向 Worker 传入和传出数据:
// Enqueue with input data:
val inputData = workDataOf("user_id" to 42)
val work = OneTimeWorkRequestBuilder<SyncWorker>()
.setInputData(inputData)
.build()
// Inside the Worker:
class SyncWorker(...) : CoroutineWorker(...) {
override suspend fun doWork(): Result {
val userId = inputData.getInt("user_id", -1)
// Pass output data back:
val output = workDataOf("synced_count" to 10)
return Result.success(output)
}
}观察任务状态
使用 getWorkInfoByIdLiveData 观察任务进度:
val workRequest = OneTimeWorkRequestBuilder<SyncWorker>().build()
WorkManager.getInstance(this).enqueue(workRequest)
WorkManager.getInstance(this)
.getWorkInfoByIdLiveData(workRequest.id)
.observe(this) { info ->
when (info?.state) {
WorkInfo.State.RUNNING -> binding.tvStatus.text = "Syncing..."
WorkInfo.State.SUCCEEDED -> binding.tvStatus.text = "Done!"
WorkInfo.State.FAILED -> binding.tvStatus.text = "Failed"
else -> {}
}
}链接任务
使用任务链按顺序或并行运行任务:
val downloadWork = OneTimeWorkRequestBuilder<DownloadWorker>().build()
val processWork = OneTimeWorkRequestBuilder<ProcessWorker>().build()
val uploadWork = OneTimeWorkRequestBuilder<UploadWorker>().build()
// Sequential: download → process → upload
WorkManager.getInstance(context)
.beginWith(downloadWork)
.then(processWork)
.then(uploadWork)
.enqueue()
// Parallel then merge:
WorkManager.getInstance(context)
.beginWith(listOf(downloadWork, processWork)) // both run in parallel
.then(uploadWork) // runs after both finish
.enqueue()WorkManager 与替代方案
应该在什么时候使用哪种方案:
- WorkManager — 可延迟、必须执行且基于约束条件的任务。最适合数据同步、上传和清理任务。
- 协程 / ViewModel — 与应用保持打开状态相关的任务。应用被终止时会停止。
- AlarmManager — 精确时间的提醒(例如日历提醒)。需要谨慎处理电量问题。
- 前台服务 — 用户知情的长时间运行任务(例如音乐播放、导航)。
快速检查
PeriodicWorkRequest 的最短重复间隔是多少?
回顾:WorkManager
WorkManager 是处理必须执行的后台任务的合适工具:
- 继承
CoroutineWorker并实现doWork() - 返回
Result.success()、.failure()或.retry() - 单次运行使用
OneTimeWorkRequest,重复运行使用PeriodicWorkRequest - 使用
Constraints添加 WiFi、低电量等条件 - 使用
workDataOf()传递数据 - 使用
beginWith().then().enqueue()链接任务
接下来:学习用于构建精美界面的 Material Design 组件。
常见问题解答
「WorkManager 与后台任务」课时是免费的吗?
是的 — 「WorkManager 与后台任务」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Android Academy 课程的其余内容,请升级到 CoddyKit PRO。 Android Academy 课程共包含 6 节课。
「WorkManager 与后台任务」这节课中我会学到什么?
使用 WorkManager 安排有保障的后台工作。使用 OneTimeWorkRequest、PeriodicWorkRequest、约束、数据传递和工作链。 你通过在浏览器中直接运行的动手代码来练习 Android Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Android Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Android Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 5 节课,共 6 节。
「WorkManager 与后台任务」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Android Academy 课中编写并运行代码吗?
能。每节 Android Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- Retrofit 与 REST API
- 使用 Coil 加载图片
- 错误处理与用户体验
- 推送通知
- WorkManager 与后台任务
- 发布到 Play Store