Android: как обработать результат WorkManager Rx? - PullRequest
0 голосов
/ 01 апреля 2019

Я разрабатываю приложение для Android, используя WorkManager (Android Jetpack) с Rx. Ниже приведен рабочий класс.

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()
        }
    }

Ух ты, вот третий код, который был написан в ответе "User One". Он отлично работает и выглядит лучше, чем второй код. Поскольку мое приложение не использует «LiveData», я не могу убедиться, что этот код действителен.

В «наблюдаем за» я вызываю «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)
                }
            }
        }
    }

1 Ответ

1 голос
/ 01 апреля 2019

Метод, который вы используете getWorkInfoById, возвращает ListenableFuture, а этот возвращает LiveData:

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

Вместо цикла while вы можете просто наблюдать статус работы, наблюдая заLiveData возвращается getWorkInfoByIdLiveData () и затем вызывает emitter.onComplete (), как только он запущен, но у вас нет здесь LifeCycle в вашем презентаторе, так что вы должны использовать applyForever () и позаботиться об удалении Observer,

Вотпример:

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) 
        }

Или просто используйте ListenableFuture, возвращаемый getWorkInfoById (), чтобы получить CallBack

...