You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过JetPack WorkManager向UI传递细粒度任务同步进度?

Great question—migrating to WorkManager while keeping your UI in sync with detailed progress is totally doable, and there are a couple of clean, architecture-friendly ways to pull it off:

1. Use WorkManager's Built-in Progress API (WorkManager 2.3+)

WorkManager added native support for real-time progress updates in version 2.3, which is tailor-made for your use case. Here's how to implement it:

  • In your Worker class: Ditch setOutputData for progress and use setProgress() to send incremental updates. This API lets you push progress data that the UI can observe directly:
    class SyncWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
        companion object {
            const val PROGRESS_CURRENT = "progress_current"
            const val PROGRESS_TOTAL = "progress_total"
        }
    
        override suspend fun doWork(): Result {
            val totalItems = 1234
            for (current in 1..totalItems) {
                // Execute your sync logic here
                
                // Push progress update
                setProgress(workDataOf(
                    PROGRESS_CURRENT to current,
                    PROGRESS_TOTAL to totalItems
                ))
    
                // Check if the task was cancelled to exit gracefully
                if (isStopped) {
                    return Result.failure()
                }
            }
            return Result.success()
        }
    }
    
  • In your ViewModel: Observe the WorkInfo LiveData from WorkManager, then map it to your existing SyncItem model (just like your current setup with switchMap):
    class SyncViewModel : ViewModel() {
        private val workManager = WorkManager.getInstance(context)
        val syncItems: LiveData<List<SyncItem>> = workManager.getWorkInfosByTagLiveData("SYNC_TAG")
            .switchMap { workInfos ->
                val items = workInfos.map { info ->
                    val current = info.progress.getInt(SyncWorker.PROGRESS_CURRENT, 0)
                    val total = info.progress.getInt(SyncWorker.PROGRESS_TOTAL, 0)
                    SyncItem("Sync Task", current, total)
                }
                MutableLiveData(items)
            }
    }
    

This approach is lightweight, integrates seamlessly with WorkManager's lifecycle, and doesn't require extra dependencies.

2. Use a Local Database for Persistent Progress Tracking

If you need progress to survive process death (critical for long-running syncs) or if you're stuck on an older WorkManager version, a local database (like Room) is the most reliable option:

  • Create a Progress Entity: Define a Room entity to store task ID, current progress, total items, and task status.
  • In your Worker: Update the database with progress at each step. Make sure to check isStopped periodically to handle cancellation and update the status accordingly.
  • In your ViewModel: Observe the database's LiveData for progress updates, then convert it to your SyncItem list. This keeps your UI in sync even if the app is backgrounded or restarted.

Handling Task Cancellation & Periodic Requests

  • Cancellation: Use WorkManager's cancelWorkById() or cancelAllWorkByTag() to stop a running task. Your Worker should check isStopped (as shown in the first example) to exit gracefully. The WorkInfo LiveData will update to State.CANCELLED, which you can use to refresh your UI state.
  • PeriodicWorkRequest: Since periodic tasks spawn a new WorkInfo for each cycle, initialize progress at the start of each run. If you need to track historical progress across cycles, the database approach is better—you can append new entries or update a dedicated "current cycle" record.

Why Not setOutputData?

You’re spot-on here—setOutputData is designed for passing results between Workers in a chain, not real-time UI updates. It only gets set once when the task completes, so it can’t handle incremental progress like "546/1234 items downloaded".

内容的提问来源于stack exchange,提问作者Andre Artus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:59:31