Android WorkManager 指南 — 后台任务调度

2026-03-02 码匠 大语言模型

WorkManager 能够在不同的 Android 版本中可靠地处理后台任务,同时尊重 Doze 模式和电池优化。

CoroutineWorker 基础

class MyCoroutineWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        return try {
            val result = performBackgroundTask()
            Result.success()
        } catch (e: Exception) {
            when {
                e is IOException -> Result.retry()
                else -> Result.failure()
            }
        }
    }

    private suspend fun performBackgroundTask(): String {
        delay(2000)
        return "Task completed"
    }
}

带约束条件的 WorkRequest

一次性工作请求:

val constraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .setRequiresBatteryNotLow(true)
    .setRequiresDeviceIdle(false)
    .build()

val workRequest = OneTimeWorkRequestBuilder<MyCoroutineWorker>()
    .setConstraints(constraints)
    .setBackoffCriteria(
        backoffPolicy = BackoffPolicy.EXPONENTIAL,
        initialDelay = 15,
        timeUnit = TimeUnit.MINUTES
    )
    .build()

WorkManager.getInstance(context).enqueueUniqueWork(
    "sync_work",
    ExistingWorkPolicy.KEEP,
    workRequest
)

周期性工作请求

val periodicWorkRequest = PeriodicWorkRequestBuilder<MyCoroutineWorker>(
    15, TimeUnit.MINUTES
).setConstraints(constraints).build()

WorkManager.getInstance(context).enqueueUniquePeriodicWork(
    "periodic_sync",
    ExistingPeriodicWorkPolicy.KEEP,
    periodicWorkRequest
)

输入/输出数据

val inputData = workDataOf(
    "user_id" to 123,
    "action" to "sync"
)

val workRequest = OneTimeWorkRequestBuilder<MyCoroutineWorker>()
    .setInputData(inputData)
    .build()

// 在 Worker 中
override suspend fun doWork(): Result {
    val userId = inputData.getInt("user_id", -1)
    val action = inputData.getString("action")

    val outputData = workDataOf(
        "result" to "success",
        "timestamp" to System.currentTimeMillis()
    )

    return Result.success(outputData)
}

WorkRequest 链式调用

顺序执行:

val uploadRequest = OneTimeWorkRequestBuilder<UploadWorker>().build()
val syncRequest = OneTimeWorkRequestBuilder<SyncWorker>().build()
val notifyRequest = OneTimeWorkRequestBuilder<NotifyWorker>().build()

WorkManager.getInstance(context)
    .beginWith(uploadRequest)
    .then(syncRequest)
    .then(notifyRequest)
    .enqueue()

并行 + 顺序执行:

val task1 = OneTimeWorkRequestBuilder<Task1Worker>().build()
val task2 = OneTimeWorkRequestBuilder<Task2Worker>().build()
val merge = OneTimeWorkRequestBuilder<MergeWorker>().build()

WorkManager.getInstance(context)
    .beginWith(listOf(task1, task2)) // 并行运行
    .then(merge) // 然后合并结果
    .enqueue()

在 Compose 中监控进度

@Composable
fun WorkProgressScreen() {
    val workManager = WorkManager.getInstance(LocalContext.current)
    val workState by workManager
        .getWorkInfoByIdLiveData(workId)
        .observeAsState()

    Column(Modifier.fillMaxSize()) {
        when {
            workState?.state == WorkInfo.State.RUNNING -> {
                val progress = workState?.progress?.getInt("progress", 0) ?: 0
                LinearProgressIndicator(progress = progress / 100f)
                Text("Progress: $progress%")
            }
            workState?.state == WorkInfo.State.SUCCEEDED -> {
                Text("Task completed successfully")
            }
            workState?.state == WorkInfo.State.FAILED -> {
                Text("Task failed")
            }
        }
    }
}

关键要点

  • 使用 CoroutineWorker 处理挂起操作

  • 设置约束条件以获得最佳执行条件

  • 使用 beginWith/then 链式调用处理复杂工作流

  • 通过 workDataOf 传递数据(JSON 可序列化类型)

  • 在 UI 中使用 observeAsState 和 Compose 监控状态

  • 为网络重试实现指数退避策略