Android retrofit2与rx顺序请求



我使用retrofit2与Rx。我有两个API调用。如果第一次调用返回代码400的空响应,我需要进行第二次API调用,如果不是,那么只是显示结果。我实现了如下所示的自定义错误处理。下面是我的解决方案:

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内部的代码?这是一个好的解决方案吗?

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

天哪,为什么每个人都把事情弄得这么复杂?在实践中,我觉得每次我需要订阅另一个subscribe中的Observable时,都有一个操作符可以为我做得更干净:

 <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链中处理,如果它可以对此做任何事情(忽略它,重试调用等)
  • 下游传播。

相关内容

  • 没有找到相关文章

最新更新