WorkManager:可延迟的保证执行 · AndroidX 源码指南
AAndroidX 源码指南
后台与启动
后台与启动 · androidx.work

WorkManager:可延迟的保证执行Work 2.12.0-beta01

用 Worker、Constraints、唯一工作、周期工作和结果语义设计后台任务。

最后更新 2026-08-01

复制即用:一次性任务

class UploadWorker(
    appContext: Context,
    params: WorkerParameters,
) : CoroutineWorker(appContext, params) {
    override suspend fun doWork(): Result = try {
        uploadPendingFiles()
        Result.success()
    } catch (error: IOException) {
        Result.retry()
    }
}

val request = OneTimeWorkRequestBuilder<UploadWorker>()
    .setConstraints(
        Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()
    )
    .build()

WorkManager.getInstance(context).enqueueUniqueWork(
    "pending-upload",
    ExistingWorkPolicy.KEEP,
    request,
)

结果语义

Result含义
Result.success()完成(不重试)
Result.failure()终止该链
Result.retry()按退避策略再次调度

幂等:Worker 可能重试或进程重建后重新运行——业务操作必须幂等(重复执行结果一致)。

Constraints:运行条件

Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .setRequiresBatteryNotLow(true)
    .setRequiresCharging(true)
    .setRequiresDeviceIdle(true)
    .build()
条件说明
NetworkTypeCONNECTED / UNMETERED / NOT_ROAMING
RequiresCharging充电时
RequiresBatteryNotLow电量充足
RequiresDeviceIdle设备空闲

边界:Constraints 是运行条件,不是立即执行承诺——不满足时任务排队等待,不是立刻跑。

任务类型选择

类型场景
一次性(OneTimeWorkRequest)上传、同步、清理
周期(PeriodicWorkRequest)定期同步(最短 15 分钟)
链式(beginWith → then)多步骤流水线
// 周期任务
val periodic = PeriodicWorkRequestBuilder<SyncWorker>(6, TimeUnit.HOURS)
    .build()

// 链式
WorkManager.getInstance(context)
    .beginWith(OneTimeWorkRequestBuilder<DownloadWorker>().build())
    .then(OneTimeWorkRequestBuilder<ProcessWorker>().build())
    .enqueue()

唯一工作:去重策略

WorkManager.getInstance(context).enqueueUniqueWork(
    "sync-task",
    ExistingWorkPolicy.KEEP,       // 已有则忽略新请求
    request,
)
Policy行为
KEEP已有进行中/排队则忽略
REPLACE取消旧的,替换新的
APPEND追加到已有任务之后

按业务语义选择;不要用随机名称绕开重复问题。

观察状态

WorkManager.getInstance(context)
    .getWorkInfoByIdLiveData(request.id)
    .observe(owner) { info ->
        when (info?.state) {
            WorkInfo.State.ENQUEUED -> {}
            WorkInfo.State.RUNNING -> {}
            WorkInfo.State.SUCCEEDED -> {}
            WorkInfo.State.FAILED -> {}
            WorkInfo.State.CANCELLED -> {}
        }
    }

什么不该用 WorkManager

  • 用户正在等待的短操作(登录、支付):用协程/线程。
  • 精确闹钟AlarmManagersetExactAndAllowWhileIdle)。
  • 持续媒体播放MediaSession + 前台服务。
  • 长时前台任务:前台服务。

WorkManager 适合可延迟、需要保证最终执行的后台任务。

常见陷阱

  • 非幂等:重试/进程重建后重复执行出错。
  • 短任务用 WorkManager:延迟不可控,用户等不了。
  • 结果丢:不观察 WorkInfo 不知道成功失败。
  • 周期最短 15 分钟:想更快用别的机制。
  • 随机工作名:去重失效。

复制即用

class SyncWorker(appContext: Context, params: WorkerParameters) :
    CoroutineWorker(appContext, params) {

    override suspend fun doWork(): Result {
        val input = inputData.getString("url") ?: return Result.failure()
        return try {
            syncFrom(input)
            Result.success()
        } catch (e: Exception) {
            if (runAttemptCount < 3) Result.retry() else Result.failure()
        }
    }
}

要点

  • success/failure/retry 三种结果;任务必须幂等。
  • Constraints 是条件非承诺;短任务/闹钟/媒体不用 WorkManager。
  • 唯一工作 + 业务语义选 Policy;链式任务用 beginWith → then。
  • 观察 WorkInfo 状态才知道结果。

相关页面