代码之家  ›  专栏  ›  技术社区  ›  dev.farmer

如何处理WorkManager Rx的结果?

  •  0
  • dev.farmer  · 技术社区  · 7 年前

    我正在开发一个Android应用程序,使用Rx的WorkManager(Android Jetpack)。 下面是工人阶级。

    class ImageRxWorker(
        appContext: Context,
        private val workerParams: WorkerParameters
    ) : RxWorker(appContext, workerParams) {
    
        override fun createWork(): Single<Result> = Single.create<Result> { emitter -
    
            // do the job
    
            emitter.onSuccess(Result.success())
        }
    
    }
    

    工作很好,没问题。 但我想知道的是我该如何处理结果?

    class MainPresenter(
        private val view: MainActivity,
        private val workManager: WorkManager = WorkManager.getInstance()
    ) : MainContract.Presenter {
    
        override fun startWork(): Completable {
            view.showToastMessage(R.string.worker_started)
    
            return Completable.create { emitter ->
                val uploadWorkRequest = OneTimeWorkRequestBuilder<ImageRxWorker>().build()
                workManager.enqueue(uploadWorkRequest)
                emitter.onComplete() // This is not exit immediately.
            }
        }
    
    }
    

    我找到了“addListener”,“result”,但我不知道如何使用它们。 我试着用谷歌搜索,但找不到任何好的参考资料。 快来人帮帮我!


    我想。。。我找到了一个解决办法。

    它起作用了!!!

    但是。。。它是。。。很难看。。。也不聪明。。。

    (在我的应用程序中,我不使用LiveData。)

        override fun startWork(): Completable {
            view.showToastMessage(R.string.worker_started)
    
            return Completable.create { emitter ->
                Log.d(TAG, "[WM][Presenter] startWork - start")
                val workRequest = OneTimeWorkRequestBuilder<ImageRxWorker>()
                    .setInputData(workDataOf("TIME" to 1000L))
                    .build()
    
                workManager.enqueue(workRequest)
    
                while (workManager.getWorkInfoById(workRequest.id).get().state != WorkInfo.State.SUCCEEDED) {
                    // Should I really polling?
                    Thread.sleep(1000)
                    Log.d(TAG, "[WM][Presenter] not yet......")
                }
    
                Log.d(TAG, "[WM][Presenter] complete")
                emitter.onComplete()
            }
        }
    

    哇,这是“用户一号”的答案写的第三个代码。 它工作得很好,看起来比第二个代码更好。 因为我的应用不使用“LiveData”,所以我无法确保此代码是否有效。

    在“observeForever”中,我在工人完成后调用“cancelWorkById”。 对吗?

        override fun startWork(): Completable {
            view.showToastMessage(R.string.worker_started)
    
            return Completable.create { emitter ->
                Log.d(TAG, "[WM][Presenter] startWork - start")
                val workRequest = OneTimeWorkRequestBuilder<ImageRxWorker>()
                    .setInputData(workDataOf("TIME" to 1000L))
                    .build()
    
                workManager.enqueue(workRequest)
    
                workManager.getWorkInfoByIdLiveData(workRequest.id).observeForever { workInfo ->
                    workInfo?.outputData?.getString("key")?.let { data ->
                        Log.d(TAG, "[WM][Presenter] startWork - complete: $data")
                        emitter.onComplete()
                        workManager.cancelWorkById(workRequest.id)
                    }
                }
            }
        }
    
    0 回复  |  直到 7 年前
        1
  •  3
  •   User One    7 年前

    使用getWorkInfoById的方法返回ListenableFuture,此方法返回LiveData:

    https://developer.android.com/reference/androidx/work/WorkManager.html#getWorkInfoByIdLiveData(java.util.UUID)

    与while循环不同,您可以通过观察getWorkInfoByIdleData()返回的LiveData来观察工作状态,然后在触发后调用emitter.onComplete(),但演示者中没有生命周期,因此您应该使用observeForRever()并注意移除观察者,

    下面是一个例子:

    workManager.getWorkInfoByIdLiveData(workRequest.id)
     .observeForever(object : Observer<WorkInfo> {
            override fun onChanged(workInfo : WorkInfo?) {
               if(workInfo.state == WorkInfo.State.SUCCEEDED) {
                 ////The Work result is a Success
                }
                /* Here We remove the Observer if Not needed anymore
                     'this' here = the Observer */
             workManager.getWorkInfoByIdLiveData(workRequest.id)
              .removeObserver(this) 
            }
    

    或者只使用getWorkInfoById()返回的ListenableFuture来获取回调