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