Android WorkManager 后台任务

FreeGuideOnline 最新 2026-07-13

kotlin class UploadLogWorker(context: Context, params: WorkerParameters) : Worker(context, params) { override fun doWork(): Result { // 执行上传逻辑 return Result.success() } }


### WorkRequest
任务请求的基类,分为两种:

- **OneTimeWorkRequest**:一次性任务,执行一次即结束。
- **PeriodicWorkRequest**:周期任务,按固定间隔重复执行。最小间隔为 15 分钟。

```kotlin
val uploadRequest = OneTimeWorkRequestBuilder<UploadLogWorker>().build()
val syncRequest = PeriodicWorkRequestBuilder<SyncWorker>(15, TimeUnit.MINUTES).build()

WorkManager

单例类,负责将 WorkRequest 入队,并可查询任务状态、取消任务等。

WorkManager.getInstance(context).enqueue(uploadRequest)

约束条件与数据传递

通过 ConstraintsData 对象精细化控制任务。

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

val inputData = Data.Builder()
    .putString("target_path", "/logs/today")
    .build()

val request = OneTimeWorkRequestBuilder<UploadLogWorker>()
    .setConstraints(constraints)
    .setInputData(inputData)
    .build()

快速上手:创建第一个后台任务

  1. build.gradle 中添加依赖:
dependencies {
    implementation "androidx.work:work-runtime-ktx:2.8.1"
}
  1. 定义 Worker:
class CleanCacheWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
    override fun doWork(): Result {
        val cacheDir = applicationContext.cacheDir
        cacheDir.listFiles()?.forEach { it.delete() }
        return Result.success()
    }
}
  1. 在 Activity 或 ViewModel 中调度任务:
val cleanRequest = OneTimeWorkRequestBuilder<CleanCacheWorker>()
    .addTag("cache_clean")
    .build()
WorkManager.getInstance(this).enqueue(cleanRequest)

任务链与任务组合

当多个任务存在先后依赖时,可使用 beginWith()then() 方法串联,或使用 combine() 处理并行任务。

val compress = OneTimeWorkRequest.from(CompressWorker::class.java)
val upload = OneTimeWorkRequest.from(UploadWorker::class.java)
val backup = OneTimeWorkRequest.from(BackupWorker::class.java)

WorkManager.getInstance(context)
    .beginWith(compress)
    .then(upload)
    .then(backup)
    .enqueue()

对于同一组任务的组合,利用 beginUniqueWork 可避免重复入队,并支持唯一命名。

WorkManager.getInstance(context).beginUniqueWork(
    "sync_chain",
    ExistingWorkPolicy.REPLACE,
    compress
).then(upload).enqueue()

观察任务状态

通过 WorkInfo 的 LiveData 形式获取任务执行状态,适用于更新 UI 进度或完成操作。

WorkManager.getInstance(this).getWorkInfoByIdLiveData(cleanRequest.id)
    .observe(this, { workInfo ->
        if (workInfo != null && workInfo.state == WorkInfo.State.SUCCEEDED) {
            showToast("缓存清理完成")
        }
    })

若需要监听所有符合标签的任务状态,可使用 getWorkInfosByTagLiveData

取消任务

// 通过 ID 取消
WorkManager.getInstance(context).cancelWorkById(cleanRequest.id)

// 通过标签取消
WorkManager.getInstance(context).cancelAllWorkByTag("cache_clean")

// 取消所有任务(慎用)
WorkManager.getInstance(context).cancelAllWork()

进阶技巧与最佳实践

使用 CoroutineWorker(Kotlin 协程集成)

继承 CoroutineWorker 可在 doWork() 中使用挂起函数,代码更简洁,自动处理线程切换。

class UploadCoroutineWorker(appContext: Context, params: WorkerParameters) : CoroutineWorker(appContext, params) {
    override suspend fun doWork(): Result {
        return withContext(Dispatchers.IO) {
            // 执行网络请求等挂起操作
            Result.success()
        }
    }
}

处理长耗时任务与通知

对于超过 10 分钟的任务,建议调用 setForeground() 保持前台服务,传递通知信息避免系统终止。

class LongRunningWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
    override suspend fun getForegroundInfo(): ForegroundInfo {
        return ForegroundInfo(NOTIFICATION_ID, createNotification())
    }
    override suspend fun doWork(): Result { ... }
    private fun createNotification(): Notification { ... }
}

设置任务重试与退避策略

当任务返回 Result.retry() 时,WorkManager 会按退避策略重新尝试。可自定义重试延迟和时间上限。

val request = OneTimeWorkRequestBuilder<UploadWorker>()
    .setBackoffCriteria(
        BackoffPolicy.EXPONENTIAL,
        OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
        TimeUnit.MILLISECONDS
    )
    .build()