[RxJava]如何通过`retryWhen()`处理网络错误 on Android RxJava × retrofit2

[RxJava]How to handle network error by `retryWhen()` on Android RxJava × retrofit2

我正在尝试使用 RxJava 进行改造的 https 请求

当网络不可用时,我想这样处理。 1、检查网络状态。 2、如果网络可用,重试请求 3、如果网络不可用,不重试 -> 之后,监听网络状态以及何时恢复,然后重试请求

我认为我们应该使用 retryWhen() 运算符,但我不知道这样做有什么好处

需要帮助才能找到好的解决方案

使用 rxJava 和 Retrofit 处理网络错误非常简单,因为它只是在 onError 方法中抛出一个 RetrofitError:

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

你应该像你说的那样使用 retryWhen 运算符。

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

参见 RxKotlinretryWhen 部分。

RetryWhen 运算符 "resubscribes" 当内部 observable 发出一个项目时(调用 Observable 的 onNext 或 Single 的 onSuccess )或者当 onError 我调用时只是不重试并向下游传递 throwable 。

以上是我的措辞;文档中的确切措辞如下:

The retryWhen operator is similar to retry but decides whether or not to resubscribe to and mirror the source Observable by passing the Throwable from the onError notification to a function that generates a second Observable, and observes its result to determine what to do. If that result is an emitted item, retryWhen resubscribes to and mirrors the source and the process repeats; if that result is an onError notification, retryWhen passes this notification on to its observers and terminates.

假设你有如下改造界面

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

在retry block中,你得到一个throwable的flowable(大部分都是HttpException从你的retrofit接口抛出),你应该在这个flowable上使用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>)。只要您在想要重试时发出一个项目,而在您不想重试时发出错误,通常选择哪种类型并不重要。