我在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
内部的代码?这样的好解决方案吗?
答案 0 :(得分:2)
1)。为了简化它,Response1
和Response2
会扩展一些基类会更好,所以在您的链中,您可以使用基类操作,可以在需要时铸造成某种类型
所以,我们假设你有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
和Response2
应覆盖BaseResponse
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();
}
});
答案 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
链中处理,如果它可以做任何事情(忽略它,重试呼叫等)