我使用RxJava + Retrofit
在我的Android应用中进行API调用。可能存在用户发出请求并且其令牌已过期的情况。在这种情况下,我在onNext
中收到正常响应,但响应不包含结果,而是包含一些代码的错误元素。如果发生这种情况,我需要重新登录用户,并且只有在获得新令牌后才重复原始请求。
所以我想用RxJava
来组织这个。
为了方便起见,我将带一个简单的例子。我们说我有以下方法:
public void test(int someInt){
Observable.just(someInt)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
log("onCompleted");
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
log("onError");
}
@Override
public void onNext(Integer integer) {
log("onNext - " + integer);
}
});
我想在调用 if (someInt == 0)
之前检查onNext()
。如果我得到false
我想继续并且调用onNext()
,但是如果我得到true
我想执行一些操作并且只重复一次原始的observable,如果条件返回false时间我不想再重复一次。
有人可以帮我弄清楚我有什么选择吗? 附:我是RX世界的新人。
答案 0 :(得分:4)
你走了。因为你想重试整个链.retry什么时候很棒,所以你必须对错误“玩”一点。
下面如果您检测到无效令牌,则会传递一个错误(仅在第一次),retryWhen将捕获并重新订阅整个rx链(从Observable.just(someInt)
开始)。
haveRetriedOnce = false;
Observable.just(someInt)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(integer ->{
if(integer == 0){
if(haveRetriedOnce){
return Observable.error(new UserOperationException());
}
// problem, throw an error and the .retryWhen will catch it
return Observable.error(new InvalidTokenException());
}else{
return Observable.just(integer);
}
})
.retryWhen(observable -> observable.flatMap(throwable->{
if(throwable instanceOf InvalidTokenException){
haveRetriedOnce = true;
return just(0); // retry, the int here is irrelevant
}else{
// other error, pass it further
return Observable.error(throwable);
}
}))
.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
log("onCompleted");
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
log("onError");
}
@Override
public void onNext(Integer integer) {
log("onNext - " + integer);
}
}