[英]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 为了简化它,最好将
Response1
和Response2
扩展一些基类,因此在您的链中,您可以使用基类进行操作,可以在需要时将其强制转换为特定类型。
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
Response1
和Response2
应该覆盖BaseResponse
2). 2)。
getResponse1
and getResponse2
should return Observable<BaseResponse>
getResponse1
和getResponse2
应该返回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
,但请确保通常对错误进行处理。
Observable
chain if it can do anything about it (ignore it, retry the calls etc) Observable
链可以执行任何操作(忽略它,重试调用等),则在Observable
链中进行处理
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.