以下是 androidx.work:work-runtime-ktx 的常见用法示例,结合 Kotlin 特性展示如何简化后台任务开发:

一、一次性任务(最简单场景)
场景:
代码实现:
class SimpleWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
// 模拟耗时操作(如延迟 2 秒)
delay(2000)
Log.d("WorkManager", "SimpleWorker 执行完成")
return Result.success() // 任务成功
}
}
// 构建任务(使用 KTX 链式配置)
val workRequest = OneTimeWorkRequestBuilder<SimpleWorker>()
.setInitialDelay(1, TimeUnit.SECONDS) // 延迟 1 秒执行
.build()
// 提交任务(KTX 扩展函数 `enqueue`)
WorkManager.getInstance(this).enqueue(workRequest)
二、周期性任务(定时执行)
场景:
代码实现:
kotlin
// 定义周期性 Worker
class DailySyncWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
// 执行数据同步逻辑
Log.d("WorkManager", "每日数据同步完成")
return Result.success()
}
}
// 调度任务(在 Application 或初始化位置)
val dailyRequest = DailyWorkRequestBuilder<DailySyncWorker>()
.setInitialDelay(9, TimeUnit.HOURS) // 首次执行时间:当前时间 + 9 小时
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED) // 要求网络连接
.build()
)
.build()
// 使用唯一任务名确保唯一性(避免重复创建)
WorkManager.getInstance(this).enqueueUniqueRepeatableWork(
"daily_sync_work", // 唯一任务名
ExistingWorkPolicy.REPLACE, // 若存在旧任务,替换为新任务
dailyRequest
)
三、组合任务(顺序 / 并行执行)
场景:
- 顺序任务:先下载文件(任务 A),再解析文件(任务 B)。
- 并行任务:同时加载图片和数据,全部完成后更新界面。
代码实现:
// 定义任务 A(下载文件)
class DownloadWorker : CoroutineWorker { /* ... */ }
// 定义任务 B(解析文件)
class ParseWorker : CoroutineWorker { /* ... */ }
// 构建任务链
val downloadRequest = OneTimeWorkRequestBuilder<DownloadWorker>().build()
val parseRequest = OneTimeWorkRequestBuilder<ParseWorker>().build()
// 使用 KTX 的 beginSequence 按顺序执行
WorkManager.getInstance(this).beginSequence(
listOf(downloadRequest, parseRequest)
).enqueue()
// 监听任务链状态(可选)
WorkManager.getInstance(this)
.getWorkInfosByTagLiveData("sequence_tag") // 给任务添加标签
.observe(this) { workInfos ->
if (workInfos.all { it.state == WorkInfo.State.SUCCEEDED }) {
Log.d("WorkManager", "顺序任务全部完成")
}
}
kotlin
// 定义任务 X(加载图片)和任务 Y(加载数据)
class LoadImageWorker : CoroutineWorker { /* ... */ }
class LoadDataWorker : CoroutineWorker { /* ... */ }
// 并行执行两个任务
WorkManager.getInstance(this).beginParallel(
listOf(
OneTimeWorkRequestBuilder<LoadImageWorker>().build(),
OneTimeWorkRequestBuilder<LoadDataWorker>().build()
)
).enqueue()
// 监听并行任务完成(所有任务成功后触发)
WorkManager.getInstance(this)
.getWorkInfosByTagLiveData("parallel_tag")
.observe(this) { workInfos ->
if (workInfos.all { it.state == WorkInfo.State.SUCCEEDED }) {
updateUI() // 更新界面
}
}
四、带输入输出数据的任务
场景:
代码实现:
class ProcessFileWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
// 获取输入数据
val filePath = inputData.getString("file_path") ?: return Result.failure()
// 模拟文件处理
Log.d("WorkManager", "处理文件:$filePath")
// 返回输出数据
val outputData = workDataOf("status" to "success", "size" to 1024)
return Result.success(outputData)
}
}
val inputData = workDataOf("file_path" to "/data/file.txt")
val workRequest = OneTimeWorkRequestBuilder<ProcessFileWorker>()
.setInputData(inputData) // 设置输入参数
.build()
WorkManager.getInstance(this).enqueue(workRequest)
kotlin
val workId = workRequest.id // 保存任务 ID
WorkManager.getInstance(this)
.getWorkInfoByIdLiveData(workId)
.observe(this) { workInfo ->
if (workInfo.state == WorkInfo.State.SUCCEEDED) {
val status = workInfo.outputData.getString("status")
Log.d("WorkManager", "任务结果:$status")
}
}
五、使用协程简化任务调度
场景:
代码实现:
kotlin
// 在协程作用域中执行
launch(Dispatchers.IO) {
// 构建任务
val workRequest = OneTimeWorkRequestBuilder<MyWorker>().build()
// 使用 KTX 的 runWorkRequest 提交任务并等待结果
val result = WorkManager.getInstance(context).runWorkRequest(workRequest)
// 处理结果
if (result == WorkManager.Result.success()) {
withContext(Dispatchers.Main) {
Toast.makeText(context, "任务成功", Toast.LENGTH_SHORT).show()
}
}
}
六、任务约束(设备状态控制)
场景:
代码实现:
kotlin
val constraints = Constraints.Builder()
.setRequiresCharging(true) // 要求设备充电
.setRequiredNetworkType(NetworkType.UNMETERED) // 要求非计量网络(如 Wi-Fi)
.setRequiresDeviceIdle(false) // 不要求设备空闲(可立即执行,若条件满足)
.build()
val uploadRequest = OneTimeWorkRequestBuilder<UploadWorker>()
.setConstraints(constraints) // 应用约束
.setBackoffCriteria( // 设置失败重试策略
BackoffPolicy.EXPONENTIAL,
initialDelay = 10,
TimeUnit.SECONDS
)
.build()
WorkManager.getInstance(this).enqueue(uploadRequest)
七、重复任务的唯一性管理
场景:
代码实现:
kotlin
// 定义唯一任务名
const val UNIQUE_WORK_NAME = "daily_report_work"
// 调度任务时检查唯一性
WorkManager.getInstance(this).enqueueUniqueRepeatableWork(
UNIQUE_WORK_NAME,
ExistingWorkPolicy.KEEP, // 若存在旧任务,保留并忽略新任务
DailyWorkRequestBuilder<ReportWorker>()
.setInitialDelay(9, TimeUnit.HOURS)
.build()
)


所有评论(0)