【问题标题】:Android WorkManager observe progressAndroid WorkManager 观察进度
【发布时间】:2020-11-17 21:09:02
【问题描述】:

我在我的应用程序中使用 WorkManager 进行延迟工作。 总工作分为多个链式工作人员,我无法向用户显示工作人员的进度(使用进度条)。

我尝试创建一个标签并将其添加到不同的工作人员,并在工作人员内部通过该标签更新进度,但是当我调试时,我总是得到进度是'0'。

我注意到的另一件事是,每次我开始工作时,workManager 的工作信息列表都会变得越来越大(即使工人完成了他们的工作)。

这是我的代码:

//inside view model
    private val workManager = WorkManager.getInstance(appContext)
    internal val progressWorkInfoItems: LiveData<List<WorkInfo>>


    init
    {
        progressWorkInfoItems = workManager.getWorkInfosByTagLiveData(TAG_SAVING_PROGRESS)
    }

    companion object
    {
        const val TAG_SAVING_PROGRESS = "saving_progress_tag"
    }

      //inside a method
        var workContinuation = workManager.beginWith(OneTimeWorkRequest.from(firstWorker::class.java))

        val secondWorkRequest = OneTimeWorkRequestBuilder<SecondWorker>()
        secondWorkRequest.addTag(TAG_SAVING_PROGRESS)
        secondWorkRequest.setInputData(createData())
        workContinuation = workContinuation.then(secondWorkRequest.build())

        val thirdWorkRequest = OneTimeWorkRequestBuilder<ThirdWorker>()
        thirdWorkRequest.addTag(TAG_SAVING_PROGRESS)
        thirdWorkRequest.setInputData(createData())
        workContinuation = workContinuation.then(thirdWorkRequest.build())

        workContinuation.enqueue()

//inside the Activity

viewModel.progressWorkInfoItems.observe(this, observeProgress())

    private fun observeProgress(): Observer<List<WorkInfo>>
    {
        return Observer { listOfWorkInfo ->
            if (listOfWorkInfo.isNullOrEmpty()) { return@Observer }

            listOfWorkInfo.forEach { workInfo ->
                if (WorkInfo.State.RUNNING == workInfo.state)
                {
                    val progress = workInfo.progress.getFloat(TAG_SAVING_PROGRESS, 0f)
                    progress_bar?.progress = progress
                }
            }
        }
    }

//inside the worker

    override suspend fun doWork(): Result = withContext(Dispatchers.IO)
    {
        setProgress(workDataOf(TAG_SAVING_PROGRESS to 10f))
        ...
        ...
        Result.success()
    }

【问题讨论】:

    标签: android android-workmanager


    【解决方案1】:

    setProgress 方法是观察单个 Worker 中的中间进度(如 guide 中所述):

    只有在 ListenableWorker 运行时才能观察和更新进度信息。

    因此,进度信息仅在 Worker 处于活动状态之前可用(例如,它不处于终端状态,如 SUCCEEDEDFAILEDCANCELLED)。 This WorkManager guide covers Worker's states.

    我的建议是使用 Worker 的唯一 ID 来识别链中的哪个 Worker 尚未处于终止状态。您可以使用WorkRequestgetId 方法来检索其唯一ID。

    【讨论】:

      【解决方案2】:

      根据我的分析,我发现你总是收到0可能有两个原因

      • setProgress 设置在工作人员的doWork() 中的Result.success() 之前,然后它会丢失,并且您永远不会在侦听器中获得该值。这可能是因为工人的状态现在是SUCCEEDED
      • 工作人员在几分之一秒内完成工作

      让我们看看下面的代码

      class Worker1(context: Context, workerParameters: WorkerParameters) : Worker(context,workerParameters) {
      
      override fun doWork(): Result {
      
          setProgressAsync(Data.Builder().putInt("progress",10).build())
          for (i in 1..5) {
              SystemClock.sleep(1000)
          }
          setProgressAsync(Data.Builder().putInt("progress",50).build())
          SystemClock.sleep(1000)
          return Result.success()
        }
      }
      

      在上面的代码中

      • 如果你只删除第一个睡眠方法,那么监听器只会得到progres50
      • 如果你只删除第二个睡眠方法,那么监听器只会得到进度10
      • 如果您同时删除两者,您将获得默认值 0

      本分析基于WorkManager 2.4.0版

      因此我发现以下方式更好且始终可靠地显示您的连锁工作的各个工人的进度。

      我有两个工人需要一个接一个地运行。如果第一个工作完成了,那么 50% 的工作就完成了,当第二个工作完成时,100% 的工作就完成了。

      两个工人

      class Worker1(context: Context, workerParameters: WorkerParameters) : Worker(context,workerParameters) {
      
      override fun doWork(): Result {
          for (i in 1..5) {
              Log.e("worker", "worker1----$i")
          }
          return Result.success(Data.Builder().putInt("progress",50).build())
        }
      }
      
      class Worker2(context: Context, workerParameters: WorkerParameters) : Worker(context,workerParameters) {
      
      override fun doWork(): Result {
          for (i in 5..10) {
             Log.e("worker", "worker1----$i")
          }
          return Result.success(Data.Builder().putInt("progress",100).build())
        }
      }
      

      活动内部

          workManager = WorkManager.getInstance(this)
      
          workRequest1 = OneTimeWorkRequest.Builder(Worker1::class.java)
                  .addTag(TAG_SAVING_PROGRESS)
                  .build()
      
          workRequest2 = OneTimeWorkRequest.Builder(Worker2::class.java)
                  .addTag(TAG_SAVING_PROGRESS)
                  .build()
      
      
         findViewById<Button>(R.id.btn).setOnClickListener(View.OnClickListener { view ->
      
              workManager?.
              beginUniqueWork(TAG_SAVING_PROGRESS,ExistingWorkPolicy.REPLACE,workRequest1)
                      ?.then(workRequest2)
                      ?.enqueue()
          })
      
          progressBar = findViewById(R.id.progressBar)
      
           workManager?.getWorkInfoByIdLiveData(workRequest1.id)
                  ?.observe(this, Observer { workInfo: WorkInfo? ->
                      if (workInfo != null && workInfo.state == WorkInfo.State.SUCCEEDED) {
                          val progress = workInfo.outputData
                          val value = progress.getInt("progress", 0)
                          progressBar?.progress =  value
                      }
                  })
      
          workManager?.getWorkInfoByIdLiveData(workRequest2.id)
                  ?.observe(this, Observer { workInfo: WorkInfo? ->
                      if (workInfo != null && workInfo.state == WorkInfo.State.SUCCEEDED) {
                          val progress = workInfo.outputData
                          val value = progress.getInt("progress", 0)
                          progressBar?.progress =  value
                      }
                  })
      

      即使工人完成了工作,每次工作开始时,workManager 的工作信息列表都会变大的原因是因为 workManager.beginWith(OneTimeWorkRequest.from(firstWorker::class.java))

      需要使用

      workManager?.beginUniqueWork(TAG_SAVING_PROGRESS, ExistingWorkPolicy.REPLACE,OneTimeWorkRequest.from(firstWorker::class.java))

      您可以阅读更多关于它的信息here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-08
        相关资源
        最近更新 更多