[RxJava]Как обрабатывать сетевые ошибки с помощью `retryWhen()` на Android RxJava × retrofit2

Я пытаюсь выполнить запрос https при модернизации с помощью RxJava.

Когда сеть недоступна, я хочу обращаться так. 1, проверьте состояние сети. 2, если сеть доступна, повторите запрос 3, если сеть недоступна, повторной попытки нет -> после этого прослушайте состояние сети и когда она вернется, затем повторите запрос

Я думаю, что мы должны использовать оператор retryWhen(), но я не знаю, как это сделать.

нужна помощь, чтобы иметь хорошее решение


person Takaya.S    schedule 25.11.2019    source источник


Ответы (2)


Вы должны использовать оператор retryWhen, как вы сказали.

http://reactivex.io/documentation/operators/retry.html

См. раздел retryWhen документа RxKotlin.

RetryWhen оператор «повторно подписывается», когда внутренний наблюдаемый испускает элемент (вызывается Observable onNext или Single onSuccess) или просто не повторяет попытку и передает бросок вниз по течению, когда onError я вызывал.

Выше моя формулировка; точная формулировка из документа выглядит следующим образом:

Оператор retryWhen аналогичен повторной попытке, но решает, следует ли повторно подписаться и зеркально отразить исходный Observable, передав Throwable из уведомления onError в функцию, которая генерирует второй Observable, и наблюдает за его результатом, чтобы определить, что делать. Если этот результат является испускаемым элементом, retryWhen повторно подписывается на источник и зеркалирует его, и процесс повторяется; если этот результат является уведомлением onError, retryWhen передает это уведомление своим наблюдателям и завершает работу.

Предположим, у вас есть следующий модифицированный интерфейс.

interface Api {
  @GET("/api")
  fun request(): Single<String>
}

В блоке повторной попытки вы получаете поток или бросаемый (который будет в основном HttpException выброшен из вашего модифицированного интерфейса). Вы должны использовать оператор flatMap для этого потока, потому что вам нужно передать бросаемый ниже по течению, когда сеть все еще недоступна.

ApiClient.instance.request()
  .retryWhen { flowable: Flowable<Throwable> ->
    flowable.flatMap { throwable ->
      // check network status here
      if (available) return@flatMap Flowable.just<Boolean>(true)
      return@flatMap Flowable.error<Boolean>(throwable)
    }
  }
  .subscribe({ response -> /* deal with success */}, { error -> /* deal with error */})

Обратите внимание, что вы должны сопоставить тип повторной попытки и брошенного случая (в данном случае Flowable<Boolean>). Обычно не имеет значения, какой тип использования выбрать, если вы выдаете элемент, когда хотите повторить попытку, и ошибку, когда не хотите.

person CoderSpinoza    schedule 25.11.2019
comment
Спасибо ! Я могу справиться, как ты сказал! - person Takaya.S; 26.11.2019

Обработка сетевых ошибок с помощью rxJava и Retrofit очень проста, так как они просто выдают RetrofitError в методе onError:

@Override
public void onError(Throwable e) {
 if (e instanceof RetrofitError) {
    if (((RetrofitError) e).isNetworkError()) {
        //handle network error
    } else {
        //handle error message from server
    }
 }
}
person Vijaya Varma Lanke    schedule 25.11.2019