RxJava的错误处理机制
- RxJava中的错误处理操作符分为两种,catch,retry
- Java把Throwable分为两种,
a. 一种是比较严重的系统问题,Error,比如OutOfMemoryErro
b. 另外一种是异常,Exception,比如RuntimeException。
c. 使用try{}catch(Exception e)无法捕捉error,需要使用try{}catch(Throwable)或者try{}catch(Error)才能捕捉error - catch操作有三种实现
a. onErrorReturn(Func1) ,遇到错误(Error/Exception)的时候不调用观察者的onError,而是创建并执行一个特殊项(Func1),再调用观察者的onComplete
b. onErrorResumeNext(Func1/Observable),遇到错误之后不调用观察者的onError,而是创建并执行一个Observable,观察者会与之前出错的被观察者接触订阅关系,转而订阅新生成的被观察者
c. onExceptionResumeNext(Observable),遇到错误之后,判断是不是Exception,如果是的话,就拦截,和onErrorResumeNext(Func1/Observable)的执行一样,如果是Error或者Throwable,就会直接调用观察者的onError函数 - Retry的操作有三项
a. retry() 无论收到多少次onError通知,都会继续订阅并重发原始Observable,直到onCompleted。
b. Retry(Long count) 接收count参数的retry会最多重新订阅count次,如果次数超过了就不会尝试再次订阅,它会把最新的一个onError通知传递给观察者
c. retryWhen(Func1) retryWhen将onError中的Throwable传递给一个函数,这个函数产生另一个Observable,retryWhen观察它的结果再决定是不是要重新订阅原始的Observable。如果这个Observable发射了一项数据,它就重新订阅,如果这个Observable发射的是onError通知,它就将这个通知传递给观察者然后终止。
retryWhen的简单例子
int retryCount = 0;
final int maxRetries = 3;
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
subscriber.onError(new RuntimeException("always fails"));
}
})
.subscribeOn(Schedulers.immediate())
.retryWhen(new Func1<Observable<? extends Throwable>, Observable<?>>() {
@Override
public Observable<?> call(Observable<? extends Throwable> observable) {
return observable.flatMap(new Func1<Throwable, Observable<?>>() {
@Override
public Observable<?> call(Throwable throwable) {
if (++retryCount <= maxRetries) {
// When this Observable calls onNext, the original Observable will be retried (i.e. re-subscribed).
System.out.println("get error, it will try after " + 1000 + " millisecond, retry count " + retryCount);
return Observable.timer(1000, TimeUnit.MILLISECONDS);
}
return Observable.error(throwable);
}
});
}
})
.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
System.out.println("onCompleted");
}
@Override
public void onNext(Integer value) {
System.out.println("onSuccess value = " + value);
}
@Override
public void onError(Throwable error) {
System.out.println("onError error = " + error);
}
});