Compose + WorkManager:后台任务处理最佳实践

2024-06-01 · 24 min · 后台任务

WorkManager 是 Android 官方推荐的后台任务解决方案,用于处理需要保证执行的延迟任务。本文将深入讲解如何在 Compose 应用中集成 WorkManager。

一、创建 Worker

class UploadLogsWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {
    
    override suspend fun doWork(): Result {
        return try {
            val userId = inputData.getString("user_id")
            uploadLogs(userId)
            Result.success()
        } catch (e: Exception) {
            Result.retry()
        }
    }
}

二、调度任务

val request = OneTimeWorkRequestBuilder<UploadLogsWorker>()
    .setInputData(workDataOf("user_id" to userId))
    .setConstraints(
        Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()
    )
    .build()

WorkManager.getInstance(context).enqueue(request)

三、在 Compose 中观察状态

@Composable
fun WorkStatusScreen(workId: UUID) {
    val context = LocalContext.current
    val workInfo by WorkManager.getInstance(context)
        .getWorkInfoByIdFlow(workId)
        .collectAsState(initial = null)
    
    when (workInfo?.state) {
        WorkInfo.State.RUNNING -> CircularProgressIndicator()
        WorkInfo.State.SUCCEEDED -> Text("完成!")
        WorkInfo.State.FAILED -> Text("失败")
        else -> Text("等待中...")
    }
}

四、带进度的 Worker

class DownloadWorker(...) : CoroutineWorker(...) {
    override suspend fun doWork(): Result {
        for (i in 0..100 step 10) {
            delay(500)
            setProgress(workDataOf("progress" to i))
        }
        return Result.success()
    }
}

// 观察进度
val progress = workInfo?.progress?.getInt("progress", 0) ?: 0

五、Hilt 集成

@HiltWorker
class SyncWorker @AssistedInject constructor(
    @Assisted context: Context,
    @Assisted params: WorkerParameters,
    private val repository: DataRepository
) : CoroutineWorker(context, params) {
    
    override suspend fun doWork(): Result {
        repository.syncData()
        return Result.success()
    }
}

六、最佳实践

总结