系列文章
RxJava系列之簡介和觀察者設計模式
RxJava系列之上游與下游
RxJava系列之常用創建型操作符
RxJava系列之常用變換操作符
RxJava系列之常用過濾操作符
RxJava系列之常用條件操作符
RxJava系列之常用合併操作符
RxJava系列之常用異常操作符
RxJava系列之線程切換實戰
RxJava系列之背壓模式
RxJava系列之配合Retrofit
RxJava系列之泛型高級
RxJava系列之手寫create操作符
RxJava系列之手寫create操作符增加泛型限定
RxJava系列之手寫just操作符
RxJava系列之手寫map操作符
RxJava系列之手寫切換線程
異常操作符
異常操作符可以攔截到上游的onError事件,從而修改發射到下游的事件。主要分爲兩大類,可以攔截throws new Exception()的和不能攔截throws new Exception的。
onErrorReturn
1.能夠接收e.onError, 2.如果接收到異常,會中斷上游後續發射的所有事件
/**
* onErrorReturn異常操作符:1.能夠接收e.onError, 2.如果接收到異常,會中斷上游後續發射的所有事件
* error
* @param view
*/
public void r01(View view) {
// 上游 被觀察者
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
for (int i = 0; i < 100; i++) {
if (i == 5) {
// RxJava中是不標準的
// throw new IllegalAccessError("我要報錯了");
// RxJava標準的
e.onError(new IllegalAccessError("我要報錯了")); // 發射異常事件
}
e.onNext(i);
}
e.onComplete();
}
})
// 在上游 和 下游之間 添加異常操作符
.onErrorReturn(new Function<Throwable, Integer>() {
@Override
public Integer apply(Throwable throwable) throws Exception {
// 處理,紀錄,異常,通知給下一層
Log.d(TAG, "onErrorReturn: " + throwable.getMessage());
return 400; // 400代表有錯誤,給下一層,目前 下游 觀察者
}
})
.subscribe(new Observer<Integer>() { // 完整版 下游 觀察者
@Override
public void onSubscribe(Disposable d) {
}
// 如果使用了 異常操作符 onNext: 400
@Override
public void onNext(Integer integer) {
Log.d(TAG, "onNext: " + integer); // 400
}
// 如果不使用 異常操作符 onError
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete: ");
}
});
}
onErrorResumeNext
onErrorResumeNext 異常操作符:1.能夠接收e.onError,
onErrorReturn可以返回標識400 VS onErrorResumeNext可以返回被觀察者(被觀察者可以再次發射多次事件給 下游)
// onErrorResumeNext 異常操作符:1.能夠接收e.onError,
// onErrorReturn可以返回標識400 對比 onErrorResumeNext可以返回被觀察者(被觀察者可以再次發射多次事件給 下游)
// error
public void r02(View view) {
// 上游
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
for (int i = 0; i < 100; i++) {
if (i == 5) {
e.onError(new Error("錯錯錯"));
} else {
e.onNext(i);
}
}
e.onComplete();
}
})
.onErrorResumeNext(new Function<Throwable, ObservableSource<? extends Integer>>() {
@Override
public ObservableSource<? extends Integer> apply(Throwable throwable) throws Exception {
// onErrorResumeNext 返回的是 被觀察者,所以再多次發射給 下游 給 觀察者接收
return Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
e.onNext(400);
e.onNext(400);
e.onNext(400);
e.onNext(400);
e.onNext(400);
e.onNext(400);
e.onComplete();
}
});
}
})
.subscribe(new Observer<Integer>() { // 下游
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer integer) {
Log.d(TAG, "onNext: " + integer);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete: ");
}
}) ;
}
onExceptionResumeNext
onExceptionResumeNext 操作符,能在發生異常的時候,扭轉乾坤,可以攔截到throws new Exception。
/**
* exception
* onExceptionResumeNext 操作符,能在發生異常的時候,扭轉乾坤,(這種錯誤一定是可以接受的,才這樣使用)
* 慎用:自己去考慮,是否該使用
* @param view
*/
public void r03(View view) {
// 上游
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
for (int i = 0; i < 100; i++) {
if (i == 5) {
/* throw new 其他Exception("錯了");
throw new IllegalAccessException("錯了");*/
throw new Exception("錯了");
// e.onError(new IllegalAccessException("錯了")); // 異常事件
} else {
e.onNext(i);
}
}
e.onComplete(); // 一定要最後執行
/**
* e.onComplete();
* e.onError
* 會報錯
*/
}
})
// 在上游和下游中間 增加 異常操作符
.onExceptionResumeNext(new ObservableSource<Integer>() {
@Override
public void subscribe(Observer<? super Integer> observer) {
observer.onNext(404); // 可以讓程序 不崩潰的
}
})
// 下游
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer integer) {
Log.d(TAG, "onNext: " + integer);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete: ");
}
});
}
retry
retry 重試操作符也屬於異常操作符,因爲可以攔截到異常。攔截到異常可以重試,重試次數可以設置,重試次數也可以獲取到。
/**
* retry 重試操作符 異常處理操作符中
* @param view
*/
public void r04(View view) {
// 上游
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
for (int i = 0; i < 100; i++) {
if (i == 5) {
/* throw new 其他Exception("錯了");
throw new IllegalAccessException("錯了");*/
// throw new Exception("錯了");
// rxJava標準的
e.onError(new IllegalAccessException("錯了")); // 異常事件
} else {
e.onNext(i);
}
}
e.onComplete(); // 一定要最後執行
}
})
// todo 演示一
/*.retry(new Predicate<Throwable>() {
@Override
public boolean test(Throwable throwable) throws Exception {
Log.d(TAG, "retry: " + throwable.getMessage());
// return false; // 代表不去重試
return true; // 一直重試,不停的重試
}
})*/
// todo 演示二 重試次數
/*.retry(3, new Predicate<Throwable>() {
@Override
public boolean test(Throwable throwable) throws Exception {
Log.d(TAG, "retry: " + throwable.getMessage());
return true;
}
})*/
// todo 演示三 打印重試了多少次,計數 Throwable + count
.retry(new BiPredicate<Integer, Throwable>() {
@Override
public boolean test(Integer integer, Throwable throwable) throws Exception {
Thread.sleep(2);
Log.d(TAG, "retry: 已經重試了:" + integer + "次 e:" + throwable.getMessage());
return true; // 重試
}
})
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer integer) {
Log.d(TAG, "onNext: " + integer);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete: ");
}
}) ;
}
總結
1.RxJava中是不標準的throw new IllegalAccessError(“我要報錯了”);
2. RxJava標準的e.onError(XXX);
3.onErrorReturn最先攔截到e.onError並且可以給下游返回一個 標識400, throw new XXX 攔截不到,整個程序奔潰
4.onErrorResumeNext最先攔截到e.onError並且可以給下游返回一個 被觀察者(還可以再次發送), throw new XXX 攔截不到,整個程序奔潰
5.onExceptionResumeNext 能在發生異常的時候,扭轉乾坤,能夠處理 throw new XXX,可以真正的讓App不奔潰
6.retry return false; 代表不去重試 return true; 不停的重試, 演示二 重試次數, 演示三 打印重試了多少次,計數