WorkManager #

一、WorkManager概述 #

WorkManager是Jetpack提供的后台任务调度组件,用于处理可延迟的后台任务,即使应用退出或设备重启也能保证任务执行。

1.1 WorkManager特点 #

  • 兼容性:支持Android 6.0及以上
  • 可靠性:任务持久化,设备重启后继续执行
  • 约束条件:支持网络、电量等约束
  • 灵活调度:支持一次性任务和周期性任务

1.2 添加依赖 #

kotlin
dependencies {
    implementation("androidx.work:work-runtime-ktx:2.9.0")
}

二、基本使用 #

2.1 创建Worker #

kotlin
class SyncWorker(
    context: Context,
    params: WorkerParameters
) : Worker(context, params) {
    
    override fun doWork(): Result {
        return try {
            // 执行后台任务
            syncData()
            
            Result.success()
        } catch (e: Exception) {
            Result.failure()
        }
    }
    
    private fun syncData() {
        // 同步数据逻辑
    }
}

2.2 使用CoroutineWorker #

kotlin
class SyncWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {
    
    override suspend fun doWork(): Result {
        return try {
            // 协程中执行
            val data = repository.fetchData()
            repository.saveData(data)
            
            Result.success()
        } catch (e: Exception) {
            Result.retry()  // 重试
        }
    }
}

2.3 调度任务 #

kotlin
// 一次性任务
val workRequest = OneTimeWorkRequestBuilder<SyncWorker>()
    .build()

WorkManager.getInstance(context).enqueue(workRequest)

// 周期性任务(最小间隔15分钟)
val periodicWorkRequest = PeriodicWorkRequestBuilder<SyncWorker>(
    1, TimeUnit.HOURS
).build()

WorkManager.getInstance(context).enqueue(periodicWorkRequest)

三、约束条件 #

3.1 设置约束 #

kotlin
val constraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)  // 需要网络
    .setRequiresBatteryNotLow(true)                  // 电量不低
    .setRequiresCharging(true)                        // 正在充电
    .setRequiresDeviceIdle(true)                      // 设备空闲
    .setRequiresStorageNotLow(true)                   // 存储不低
    .build()

val workRequest = OneTimeWorkRequestBuilder<SyncWorker>()
    .setConstraints(constraints)
    .build()

3.2 网络类型 #

类型 说明
NetworkType.CONNECTED 任意网络连接
NetworkType.UNMETERED 非计费网络(WiFi)
NetworkType.NOT_ROAMING 非漫游网络
NetworkType.METERED 计费网络

四、任务配置 #

4.1 输入数据 #

kotlin
val inputData = workDataOf(
    "key1" to "value1",
    "key2" to 123
)

val workRequest = OneTimeWorkRequestBuilder<SyncWorker>()
    .setInputData(inputData)
    .build()
kotlin
class SyncWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
    
    override fun doWork(): Result {
        val key1 = inputData.getString("key1")
        val key2 = inputData.getInt("key2", 0)
        
        // 使用数据
        
        return Result.success()
    }
}

4.2 输出数据 #

kotlin
override fun doWork(): Result {
    val result = doSomething()
    
    val outputData = workDataOf(
        "result" to result
    )
    
    return Result.success(outputData)
}

4.3 重试策略 #

kotlin
val workRequest = OneTimeWorkRequestBuilder<SyncWorker>()
    .setBackoffCriteria(
        BackoffPolicy.LINEAR,
        30,
        TimeUnit.SECONDS
    )
    .build()

4.4 标签 #

kotlin
val workRequest = OneTimeWorkRequestBuilder<SyncWorker>()
    .addTag("sync")
    .build()

// 取消带标签的任务
WorkManager.getInstance(context).cancelAllWorkByTag("sync")

// 获取带标签的任务状态
WorkManager.getInstance(context).getWorkInfosByTagLiveData("sync")

五、链式任务 #

5.1 任务链 #

kotlin
WorkManager.getInstance(context)
    .beginWith(listOf(workA, workB))
    .then(workC)
    .then(workD)
    .enqueue()

5.2 唯一任务链 #

kotlin
WorkManager.getInstance(context)
    .beginUniqueWork(
        "unique_work",
        ExistingWorkPolicy.REPLACE,
        workA
    )
    .then(workB)
    .enqueue()

5.3 ExistingWorkPolicy #

策略 说明
REPLACE 取消现有任务,添加新任务
KEEP 保留现有任务,忽略新任务
APPEND 将新任务追加到现有任务链末尾
APPEND_OR_REPLACE 追加或替换

六、观察任务状态 #

6.1 监听任务状态 #

kotlin
WorkManager.getInstance(context)
    .getWorkInfoByIdLiveData(workRequest.id)
    .observe(this) { workInfo ->
        when (workInfo?.state) {
            WorkInfo.State.ENQUEUED -> { }
            WorkInfo.State.RUNNING -> { }
            WorkInfo.State.SUCCEEDED -> { }
            WorkInfo.State.FAILED -> { }
            WorkInfo.State.BLOCKED -> { }
            WorkInfo.State.CANCELLED -> { }
            null -> { }
        }
    }

6.2 获取输出数据 #

kotlin
WorkManager.getInstance(context)
    .getWorkInfoByIdLiveData(workRequest.id)
    .observe(this) { workInfo ->
        if (workInfo?.state == WorkInfo.State.SUCCEEDED) {
            val result = workInfo.outputData.getString("result")
        }
    }

七、取消任务 #

kotlin
// 取消单个任务
WorkManager.getInstance(context).cancelWorkById(workRequest.id)

// 取消带标签的任务
WorkManager.getInstance(context).cancelAllWorkByTag("sync")

// 取消唯一任务链
WorkManager.getInstance(context).cancelUniqueWork("unique_work")

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

八、前台服务 #

8.1 创建前台Worker #

kotlin
class ForegroundWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {
    
    override suspend fun doWork(): Result {
        setForeground(
            ForegroundInfo(
                NOTIFICATION_ID,
                createNotification()
            )
        )
        
        // 执行任务
        return Result.success()
    }
    
    private fun createNotification(): Notification {
        return NotificationCompat.Builder(applicationContext, CHANNEL_ID)
            .setContentTitle("正在同步")
            .setContentText("同步数据中...")
            .setSmallIcon(R.drawable.ic_sync)
            .build()
    }
}

8.2 调度前台任务 #

kotlin
val workRequest = OneTimeWorkRequestBuilder<ForegroundWorker>()
    .build()

WorkManager.getInstance(context).enqueue(workRequest)

九、最佳实践 #

9.1 使用唯一任务 #

kotlin
// 避免重复任务
WorkManager.getInstance(context)
    .enqueueUniqueWork(
        "sync_data",
        ExistingWorkPolicy.KEEP,
        workRequest
    )

9.2 合理设置约束 #

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

9.3 处理任务结果 #

kotlin
override suspend fun doWork(): Result {
    return try {
        val result = performTask()
        if (result.isSuccess) {
            Result.success(workDataOf("data" to result.data))
        } else {
            Result.failure(workDataOf("error" to result.error))
        }
    } catch (e: Exception) {
        Result.retry()
    }
}

十、总结 #

本章详细介绍了WorkManager:

  1. WorkManager的基本概念
  2. Worker的创建和使用
  3. 约束条件配置
  4. 任务输入输出数据
  5. 链式任务
  6. 观察任务状态
  7. 取消任务
  8. 前台服务
  9. 最佳实践

WorkManager是Android后台任务处理的推荐方案,适合处理可延迟的后台任务。

最后更新:2026-03-26