RxJava for Android:Expose Exception和Retry(with delay)

时间:2015-09-18 11:28:29

标签: android rx-java rx-android

我有以下Observable,它将每30秒执行一次带有Retrofit的REST调用:

 Subscription subscription = Observable.interval(0, REFRESH_INTERVAL, TimeUnit.SECONDS)
        .concatMap(new Func1<Long, Observable<Response>>() {
           @Override
           public Observable<Response> call(Long time) {
              return webservice.callRetrofitServiceWithRx(parameter);
           }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new UpdateSuccessAction(), new UpdateErrorAction());

可能会发生(特别是REST-Call)抛出异常(例如没有互联网连接)。

我想要实现的目标:

Observable应该发出/暴露异常,以便我可以在UI上显示错误消息,但它应该继续发出项目(在30秒内重试)。

目前正在研究

  • 如果我没有定义任何特殊行为,Observable会发出异常并停止工作(=不在30秒内重试)。

  • 如果我尝试重试操作符,则会吞下异常但不会暴露异常,因此我无法在ui中显示错误。

  • 如果我尝试onErrorReturn运算符,我可以处理异常,但据我所知,不能重试。

解决方法

我目前的解决方法是重新订阅此Observable,但我想知道某人是否有更优雅的解决方案。

2 个答案:

答案 0 :(得分:4)

我假设doOnError符合您的需要(用于记录错误),并结合重试,例如:

Subscription subscription = Observable.interval(0, REFRESH_INTERVAL, TimeUnit.SECONDS)
    .concatMap(new Func1<Long, Observable<Response>>() {
       @Override
       public Observable<Response> call(Long time) {
          return webservice.callRetrofitServiceWithRx(parameter);
       }
    })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .doOnError(new UpdateErrorAction())
    .retry()
    .subscribe(new UpdateSuccessAction());

答案 1 :(得分:1)

如果找到解决方案,请在另一个答案的帮助下。

首先我定义了一个RetryWithDelay-Function,它在30秒后开始重试,而不是立即重试。

 private static class RetryWithDelay
     implements Func1<Observable<? extends Throwable>, Observable<?>> {

  @Override
  public Observable<?> call(Observable<? extends Throwable> attempts) {
     return attempts.flatMap(new Func1<Throwable, Observable<?>>() {
        @Override
        public Observable<?> call(Throwable throwable) {
           return Observable.timer(CallBO.REFRESH_INTERVAL_IN_SEC,             }
     });
  }
}

然后我在这个Observable-Chain中使用了它:

Subscription subscription = Observable.interval(0, REFRESH_INTERVAL, TimeUnit.SECONDS)
.concatMap(new Func1<Long, Observable<Response>>() {
   @Override
   public Observable<Response> call(Long time) {
      return webservice.callRetrofitServiceWithRx(parameter);
   }
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(new UpdateErrorAction())
.retryWhen(new RetryWithDelay())
.subscribe(new UpdateSuccessAction());