2015-06-17 4 views
1

У меня есть этот код, чтобы подключиться к серверу xmpp. Все работает отлично, за исключением последнего attemp, чтобы попытаться подключиться, onError не вызывается на абонента, и, согласно документу, он должен. Что я делаю не так?rxjava android retryКогда не вызывается 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: на последнюю попытку, общественный недействительный OnError следует назвать и не

+0

Я думаю, вам нужно flatMap в ошибке() наблюдаемый для retryWhen, чтобы бросить. – akarnokd

ответ

1

У вас есть:

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

этот код никогда не будет генерировать ошибку, так что будет пытаться экспоненциально (Таймер), чтобы повторить попытку, но никогда не потерпит неудачу. Таким образом, onError() никогда не будет вызван.

Если вы хотите поймать ошибку, вам необходимо передать ее из retryWhen с явным Observable.error() или удалить деталь retryWhen. :)

+0

Как явным образом передать его из retryWhen? –

+0

Далее в цепочке? 'Observable.onError (throwable)', например. 'if (throwable instanceOf IllegalStateException) {return onError (throwable} else {...}' – Diolor

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 с первым элементом без пары. Было бы хорошо

Смежные вопросы