跳转到正文
YGJoon
返回

Android Kotlin WorkManager 后台任务策略

编辑文章

核心特点

基础配置

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

class App : Application(), Configuration.Provider {
    override fun getWorkManagerConfiguration(): Configuration {
        return Configuration.Builder()
            .setMinimumLoggingLevel(Log.INFO)
            .build()
    }
}

定义 Worker

class SyncWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
    override suspend fun doWork(): Result {
        return try {
            repository.sync()
            Result.success()
        } catch (e: IOException) {
            Result.retry()
        }
    }
}

约束与调度

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

val workRequest = OneTimeWorkRequestBuilder<SyncWorker>()
    .setConstraints(constraints)
    .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30.seconds)
    .build()

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

链式任务

WorkManager.getInstance(context)
    .beginWith(OneTimeWorkRequestBuilder<UploadWorker>().build())
    .then(OneTimeWorkRequestBuilder<NotifyWorker>().build())
    .enqueue()

周期性任务

val periodicWork = PeriodicWorkRequestBuilder<SyncWorker>(12, TimeUnit.HOURS)
    .setConstraints(constraints)
    .build()

WorkManager.getInstance(context).enqueueUniquePeriodicWork(
    "periodic_sync", ExistingPeriodicWorkPolicy.UPDATE, periodicWork
)

输入输出数据

val request = OneTimeWorkRequestBuilder<UploadWorker>()
    .setInputData(workDataOf("filePath" to filePath))
    .build()

class UploadWorker(...): CoroutineWorker(...) {
    override suspend fun doWork(): Result {
        val filePath = inputData.getString("filePath") ?: return Result.failure()
        val success = uploader.upload(filePath)
        return if (success) Result.success(workDataOf("url" to "https://...")) else Result.retry()
    }
}

与 Hilt 集成

@HiltWorker
class SyncWorker @AssistedInject constructor(
    @Assisted context: Context,
    @Assisted params: WorkerParameters,
    private val repository: SyncRepository
) : CoroutineWorker(context, params) { ... }

@Module
@InstallIn(SingletonComponent::class)
abstract class WorkerModule {
    @Binds
    abstract fun bindWorkerFactory(factory: HiltWorkerFactoryImpl): ChildWorkerFactory
}

运行状态监听

WorkManager.getInstance(context)
    .getWorkInfosForUniqueWorkLiveData("sync")
    .observe(lifecycleOwner) { workInfos ->
        workInfos.firstOrNull()?.let { info ->
            when (info.state) {
                WorkInfo.State.SUCCEEDED -> showToast("Sync success")
                WorkInfo.State.FAILED -> showToast("Sync failed")
                else -> Unit
            }
        }
    }

常见问题

问题原因解决方案
周期任务不执行周期 < 15 分钟或约束不满足确保最小周期大于 15 分钟,检查约束
任务重复未设置唯一工作策略使用 enqueueUniqueWork 或 KEEP 策略
资源占用高过多任务并行通过 WorkManager.initialize 设置最大并行数

总结

  1. WorkManager 是保障型后台任务首选,结合协程可编写可读的异步逻辑。
  2. 注意唯一工作策略、约束配置,与应用生命周期保持一致。
  3. 搭配 Hilt、Flow 等组件能实现状态追踪与依赖注入,提升整体可维护性。

编辑文章
分享这篇文章:

上一篇
Android Kotlin 函数式编程与控制流
下一篇
Android Kotlin Wear OS 与 Compose 多端协同