rxjava android retry在最后一次尝试时不调用onError

时间:2015-06-17 12:02:38

标签: android android-activity rx-java

我有这个代码尝试连接到xmpp服务器。一切正常,除了在最后尝试连接的尝试,onError没有在订阅者上调用,根据文档,它应该。我做错了什么?

@Override
public void connect(final AbstractXMPPConnection connection) {
    Observable.<AbstractXMPPConnection>create(subscriber -> {
        try {
            connection.connect();
        } catch (SmackException | IOException | XMPPException e) {
            e.printStackTrace();
            subscriber.onError(e);
        }
        })
         .retryWhen(attempts -> attempts.zipWith(Observable.range(1, 4), (n, i) -> i).flatMap(i -> {
             return Observable.timer(i, TimeUnit.SECONDS);
         }))
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<AbstractXMPPConnection>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {
                     if (callback != null)
                        callback.onFailedConnecting();
                }

                @Override
                public void onNext(AbstractXMPPConnection conn) {
                    if (callback != null)
                        callback.onConnected();
                }
            });
}

TLDR:在最后一次尝试时,应该调用public void onError,它不是

2 个答案:

答案 0 :(得分:1)

你有:

.retryWhen(attempts -> attempts.zipWith(Observable.range(1, 4), (n, i) -> i).flatMap(i -> {        
   return Observable.timer(i, TimeUnit.SECONDS);
}))

此代码永远不会发出错误,因此它将以指数方式(Timer)重试但永远不会失败。因此永远不会调用onError()。

如果你想捕获错误,你需要通过显式的Observable.error()从retryWhen传递它,或者删除retryWhen部分。 :)

答案 1 :(得分:0)

我这样做了(Scala,RxScala):

.retryWhen(_
    .zipWith(Observable.just(1, 2, 3, -1))((t, i) => (t, i))
    .flatMap( tuple => tuple match {
      case (t, -1) => Observable.error(t)
      case (t, i) => Observable.timer(i seconds)
    }))

可能存在某种zipWith运算符,它使用第一个非对元素调用onError。这将是很好的