Как перестать наблюдать старые статусы ответов RxJava без утилизации? - PullRequest
0 голосов
/ 22 июня 2019

У меня есть такой случай. Пользователь запускает цепочку запросов, нажимая кнопку. Затем он сделает две загрузки фотографий. Однако после начала загрузки фотографий он может вернуться и начать процесс заново.

My CompositeDisposable () присоединен к viewMode l, он будет очищен только после onCleared (). Вот почему возникает странная проблема: пользователь может начать загрузку фотографий, вернуться назад, начать заново и ответы на старые запросы будут доставлены, до загрузки новых!

Как мне изменить все мои обычные запросы RxJava и оператор zip так, чтобы они смотрели только после новых, а не старых запросов.

Опять же, я не могу вызвать CompositeDisposable.dispose (), перед каждым событием кнопки, потому что это завершит процесс загрузки.

Мне нужно только удалить возможные старые ответы.

& # x200B;

Вот мой образец:

//called two times, for uploading
fun uploadPhoto(){
compositeDisposable.add(
            apiService.networkRequest(linkedHashMap, url)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribeWith(object: DisposableSingleObserver<retrofit2.Response<String>>() {
                        override fun onSuccess(t: retrofit2.Response<String>) {
                            // will provide result even if two new uploadPhoto() methods gets called
                            handleResponse(t)
                        }

                        override fun onError(e: Throwable) {

                        }
                    }))

}
}

& # x200B;

fun handleResponse(response: retrofit2.Response<String>)
{
    responseList.add(response) //saves number of responses
    if(responseList.size == 2)
    {
        //calls new network request and creates a new logic. 
    }
}

Проблема в том, что handleResponse () вызывается после того, как uploadPhoto () возвращает предыдущий результат

1 Ответ

1 голос
/ 22 июня 2019

ОК, если я правильно понял ваш случай, вы хотите отменить ответ от первой загрузки и принять во внимание ответ от второй или обобщить: игнорируйте любые предыдущие ответы и принимайте во внимание только самые последние.

Если это так, то одним простым решением будет проверять compositeDisposable каждый раз перед началом новой загрузки.Если список не пустой, то отбросьте все и добавьте в него новый одноразовый.

Примерно так:

fun uploadPhoto(){
   if(compositeDisposable.size() > 0){
       compositeDisposable.clear()
   }

   // ...
}

Обратите внимание на использование compositeDisposable.clear(), а не .dispose().

Относительно вашего последующего вопроса:

Итак, вызов compositeDisposable.clear() удалит каждый элемент в списке, более конкретно это означает, что рабочий поток будетпрервано и, да, в вашем случае это означает, что процесс загрузки будет прерван.

Если вы хотите, чтобы загрузка продолжалась, вам придется придумать другой механизм, отличный от очистки одноразовых.

Я не уверен, что вы могли бы сделать это в Rx, но одной идеей, не связанной с Rx, было бы иметь какой-то uploadId, например, сгенерированный случайный хэш, связанный с каждой загрузкой.Этот идентификатор должен быть передан вашему сетевому уровню и затем возвращен в ответе.

Затем в ViewModel вы будете отслеживать currentUploadId и:

  • всякий раз, когда пользователь выполняет новую загрузку, обновляйте currentUploadId с новым сгенерированным идентификатором
  • при получении handleResponse(...), вы проверяете response.uploadId с currentUploadId, если они не совпадают, вы просто отбрасываете этоответ.
...