简体   繁体   English

带有RX顺序请求的Android Retrofit2

[英]Android retrofit2 with rx sequential requests

I'm using retrofit2 with Rx. 我正在将Retrofit2与Rx一起使用。 I have two API calls. 我有两个API调用。 If first call returns empty response with code 400 I need to make second API call, if not then just to show result. 如果第一次调用返回的代码为400,则为空响应,我需要进行第二次API调用,否则请为显示结果。 I've implemented custom error handling how shown here . 我实现了自定义错误处理如何显示在这里 Here is my solution: 这是我的解决方案:

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

Is it possible to simplify this code that goes inside method onClientError ? 是否可以简化方法onClientError代码? Is it good solution to like that? 这样好解决吗?

1). 1)。 To simplify it, it would be better that Response1 and Response2 will extend some base class, so in your chain, you can operate with base class, which can be casted to certain type when needed 为了简化它,最好将Response1Response2扩展一些基类,因此在您的链中,您可以使用基类进行操作,可以在需要时将其强制转换为特定类型。

So, let's assume, that you have BaseResponse : 因此,假设您具有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
}

Response1 and Response2 should override BaseResponse Response1Response2应该覆盖BaseResponse

2). 2)。 getResponse1 and getResponse2 should return Observable<BaseResponse> getResponse1getResponse2应该返回Observable<BaseResponse>

3). 3)。 Your target code: 您的目标代码:

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

Jeesh, why does everyone make it so complicated? esh,为什么每个人都这么复杂? In practice I've felt that every time I needed to subscribe to an Observable in the subscribe of another, there is an operator that will do it much more cleanly for me: 在实践中,我觉得每次需要在另一个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());

If you have special error handling needs, create a custom Subscriber that handles that, but make sure that error handling in general is 如果您有特殊的错误处理需求,请创建一个可处理该错误的自定义Subscriber ,但请确保通常对错误进行处理。

  • handled in the Observable chain if it can do anything about it (ignore it, retry the calls etc) 如果Observable链可以执行任何操作(忽略它,重试调用等),则在Observable链中进行处理
  • propagated downstream. 向下游传播。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM