2016-09-30 63 views
2

我有一個RxJava實現的下面的類,用於從API下載兩個資源。我做了一些rx來允許它在不符合api /連接要求時重試或重複。但是,我不能讓retryWhen()嘗試超過3次後觸發onError()。RxJava make retryWhen()激發onError()方法

問題/ HELP

請查看我的代碼,並幫我解決這個問題。

注意

我通過閱讀這兩篇文章的Rx實現。 article 1article 2

SplashPresenter.class

public class SplashPresenter implements SplashContract.Presenter { 

    private static final String TAG = SplashPresenter.class.getName(); 
    private static final int RETRY_TIMEOUT = 10; 
    private static final int STOP_RETRY_TIME = 3; 
    private static final int START_RETRY_TIME = 1; 


    private SplashContract.View mView; 

    @Override 
    public void init(SplashContract.View view) { 
     this.mView = view; 
    } 

    @Override 
    public void onResume() { 

     GetRemoteReceiverRelationshipSpec relationSpec = new GetRemoteReceiverRelationshipSpec(); 
     GetRemoteIncompleteReasonSpec reasonSpec = new GetRemoteIncompleteReasonSpec(); 

     Observable<RepoResult<ArrayList<IncompleteReasonViewModel>>> queryReason = 
       Repository.getInstance().query(reasonSpec); 

     Repository.getInstance().query(relationSpec) 
       .concatMap(result -> queryReason) 
       .repeatWhen(complete -> complete 
         .zipWith(Observable.range(START_RETRY_TIME, STOP_RETRY_TIME), (v, i) -> i) 
         .flatMap(repeatCount -> { 
          Log.i(TAG, "Repeat attempt: " + repeatCount); 
          mView.showLoadingDialog(); 
          return Observable.timer(RETRY_TIMEOUT, 
            TimeUnit.SECONDS); 
         })) 
       .takeUntil(RepoResult::isSuccess) 
       .retryWhen(error -> error 
         .zipWith(Observable.range(START_RETRY_TIME, STOP_RETRY_TIME), (v, i) -> i) 
         .flatMap(retryCount -> { 
          Log.i(TAG, "Retry attempt: " + retryCount); 
          mView.showLoadingDialog(); 
          if (mView.getCommunicator() != null) { 
           mView.getCommunicator().onConnectionFail(retryCount); 
          } 
          return Observable.timer(RETRY_TIMEOUT, 
            TimeUnit.SECONDS); 
         })) 
       .filter(RepoResult::isSuccess) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribe(
         result -> Log.i(TAG, "onNext()"), 
         err -> { 
          Log.i(TAG, "onError()"); 
          if (mView.getCommunicator() != null) { 
           mView.dismissLoadingDialog(); 
           mView.getCommunicator().onSplashScreeDismissError(); 
          } 
         }, 
         () -> { 
          Log.i(TAG, "onComplete()"); 
          if (mView.getCommunicator() != null) { 
           mView.dismissLoadingDialog(); 
           mView.getCommunicator().onSplashScreenSuccessDismiss(); 
          } 
         } 
       ); 
    } 

    @Override 
    public void onPause() { 

    } 
} 

回答

0

當我以前寫過類似的代碼,我在flatMap

.flatMap(retryCount -> { 
    if (retryCount >= STOP_RETRY_TIME) { 
     return Observable.error(someException); 
    } 
    return Observable.timer(RETRY_TIMEOUT, TimeUnit.SECONDS); 
})) 
+0

好的,我會試試這個並且反饋給你。謝謝@ytRino –

+0

@JongzPuangput嗨,之後發生了什麼。 – ytRino

+0

它工作就像一個魅力,thx(sry,對於遲到的反應) –

1

了手動扔Observable.error()要保留在重試之後拋出(而不是發射一個自定義的),當retryCount爲時,從zipWith運算符返回一個具有相應錯誤的Observable超過指定的限制。

.retryWhen(error -> { 
       Observable<Integer> range = Observable.range(START_RETRY_TIME, STOP_RETRY_TIME); 
       Observable<Observable<Long>> zipWith = error.zipWith(range, (e, i) -> 
         i < STOP_RETRY_TIME ? 
           Observable.timer(i, TimeUnit.SECONDS) : 
           Observable.error(e)); 
       return Observable.merge(zipWith); 
      });