2016-10-05 8 views
1

私はretrofit2をRxで使用しています。私は2つのAPIコールを持っています。最初の呼び出しがコード400の空の応答を返す場合は、2番目のAPI呼び出しを作成する必要があります。私は表示されたカスタムエラー処理を実装しましたhere。ここに私の解決策は次のとおりです。Androidのretrofit2とrxの順次リクエスト

getResponse1(token) 
      .subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new ObserverErrorImpl<Response1, BaseError>(BaseError.class) { 
       @Override 
       public void onNext(Response1 response) { 
        view.onSuccess(response); 
       } 

       @Override 
       public void onClientError(BaseError response) { 
        getResponse2(token) 
          .subscribeOn(Schedulers.newThread()) 
          .observeOn(AndroidSchedulers.mainThread()) 
          .subscribe(new ObserverErrorImpl<Response2, BaseError>(BaseError.class) { 

           @Override 
           public void onNext(Response2 response) { 
            view.onSuccess(response); 
            view.hideProgress(); 
           } 

           @Override 
           public void onError(Throwable throwable) { 
            super.onError(throwable); 
            view.hideProgress(); 
           } 
          }); 
       } 

       @Override 
       public void onError(Throwable throwable) { 
        super.onError(throwable); 
        view.hideProgress(); 
       } 
      }); 

は方法onClientError内部に入るこのコードを単純化することが可能ですか?それを好きなのは良い解決策ですか?

答えて

2

1)。それを簡略化するために、それは、あなたがそう

を必要なときに、特定の型にキャストすることができ、基本クラス、で動作することができ、あなたのチェーンのよう Response1Response2は、いくつかの基本クラスを拡張することが良いでしょう、のは、あることを想定してみましょうあなたは BaseResponseを持っている:

public abstract class BaseResponse{ 

    public static int TYPE_RESPONSE_1 = 1; 
    public static int TYPE_RESPONSE_2 = 2; 

    public abstract int getType(); //every class MUST override this method 
} 

Response1Response2BaseResponse

2)をオーバーライドする必要があります。getResponse1およびgetResponse2は、Observable<BaseResponse>

3)を返す必要があります。ターゲットコード:

getResponse1(token) 
      .onErrorResumeNext(new Func1<Throwable, Observable<BaseResponse>>() { 
       @Override 
       public Observable<BaseResponse> call(Throwable throwable) { 
        // I use Retrofit 1.9 
        // And in Retrofit 1.9 I have class RetrofitError, which may provide me all info about error 
        // I'm absolutelly sure Retrofit 2 also have such class, 
        // but it may have another name 
        if(/* is your target error */){ 
         //cast it tour target error 
         return getResponse2(token); 
        } 
        return Observable.error(throwable); 
       } 
      }) 
      .subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new ObserverErrorImpl<Response1, BaseError>(BaseError.class) { 
       @Override 
       public void onNext(BaseResponse response) { 
        if(response.getType() == BaseResponse.TYPE_RESPONSE_1){ 
         view.onSuccess(response); 
        } else { 
         view.onSuccess(response); 
         view.hideProgress(); 
        } 
       } 

       @Override 
       public void onError(Throwable throwable) { 
        super.onError(throwable); 
        view.hideProgress(); 
       } 
      }); 
0

ジエ、なぜ誰もがそれをとても複雑にしていますか?

<T,E extends Throwable> Observable<T> 
whenExceptionIs(Class<E> what, Func1<E,Observable<T>> result) { 
    return t -> { 
     return what.isInstance(t) ? result.call(t) : Observable.error(t); 
    }; 
} 

getResponse1(token) 
.onErrorResumeNext(whenExceptionIs(BaseError.class, getResponse2(token))) 
.subscribeOn(Schedulers.newThread()) 
.observeOn(AndroidSchedulers.mainThread()) 
.subscribe(view::onSuccess, view::hideProgress, err -> view.hideProgress()); 

あなたは特別なエラー処理のニーズをお持ちの場合:実際には私は別のsubscribeObservableに加入するために必要なすべての時間は、私にとってははるかにきれいにそれを行いますオペレータがあることを感じていました、ということを処理するカスタムSubscriberを作成し、一般的にはエラー処理が、それはそれについて何かを行うことができればObservableチェーンで扱わ

  • であることを確認してください
  • が下流に伝播(通話などを再試行し、それを無視)します。
関連する問題