带有rx顺序请求的Android retrofit2

时间:2016-10-05 19:32:35

标签: android retrofit rx-java

我在rx中使用retrofit2。我有两个API调用。如果第一次调用返回带代码400的空响应,我需要进行第二次API调用,如果没有则只显示结果。我已经实现了显示here的自定义错误处理方式。这是我的解决方案:

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 个答案:

答案 0 :(得分: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
}

Response1Response2应覆盖BaseResponse

2)。 getResponse1getResponse2应该返回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();
                }
            });

答案 1 :(得分:0)

Jeesh,为什么每个人都这么复杂?在实践中,我觉得每次我需要订阅另一个Observable中的subscribe时,都会有一个操作员为我做得更干净:

 <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());

如果您有特殊的错误处理需求,请创建一个处理该问题的自定义Subscriber,但一定要确保错误处理

  • Observable链中处理,如果它可以做任何事情(忽略它,重试呼叫等)
  • 传播到下游。