系列文章
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; 不停的重试, 演示二 重试次数, 演示三 打印重试了多少次,计数