RxJava3.0 操作符之错误处理操作符使用
错误处理操作符简介
错误处理操作符 帮助从 Observable发出的错误通知中 恢复或做出反应.
例如我们可以:
- 接收错误并切换到一个备份可观察者以继续序列
- 接收错误并发出一个默认项
- 接收错误并且立即尝试重启这个失败的Observable
- 接收错误并且在一定时间间隔后尝试重启这个失败的Observable
错误处理操作符分类
错误处理操作符分为两类
-
Catch ― 拦截原始Observable的
onError
通知,将它替换为其它的数据项或数据序列,让产生的Observable能够正常终止或者根本不终止. -
Retry
— 当原始Observable 发出一个错误通知,不会将通知传递给onError
,而是重新订阅以期望他能正常完成.
错误处理操作符使用示例
Catch
onErrorComplete
拦截源Observable错误通知,并将其转换为完成通知发出
也可指定一个Predicate,用以控制何时对错误通知转换成完成通知,何时不转换.
private void onErrorComplete() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
emitter.onNext("A");
emitter.onNext("B");
emitter.onError(new Throwable("出错了"));
emitter.onNext("C");
}
}).onErrorComplete()
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull String s) {
Log.i(TAG, "onErrorComplete onNext: " + s);
}
@Override
public void onError(@NonNull Throwable e) {
Log.i(TAG, "onErrorComplete onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.i(TAG, "onErrorComplete onComplete" );
}
});
}
输出:
27799-27799/com.sky.rxjava I/sky>>>: onErrorComplete onNext: A
27799-27799/com.sky.rxjava I/sky>>>: onErrorComplete onNext: B
27799-27799/com.sky.rxjava I/sky>>>: onErrorComplete onComplete
onErrorResumeNext
拦截源Observable错误通知,转换为一个Observable 发出一系列项.
private void onErrorResumeNext() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
emitter.onNext("A");
emitter.onNext("B");
emitter.onError(new Throwable("出错了"));
emitter.onNext("C");
}
}).onErrorResumeNext(new Function<Throwable, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Throwable throwable) throws Throwable {
return Observable.just("X", "Y", "Z");
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
Log.i(TAG, "onErrorResumeNext: " + s);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Throwable {
Log.i(TAG, "onErrorResumeNext onError: " + throwable.getMessage());
}
});
}
输出:
29457-29457/com.sky.rxjava I/sky>>>: onErrorResumeNext onNext: A
29457-29457/com.sky.rxjava I/sky>>>: onErrorResumeNext onNext: B
29457-29457/com.sky.rxjava I/sky>>>: onErrorResumeNext onNext: X
29457-29457/com.sky.rxjava I/sky>>>: onErrorResumeNext onNext: Y
29457-29457/com.sky.rxjava I/sky>>>: onErrorResumeNext onNext: Z
29457-29457/com.sky.rxjava I/sky>>>: onErrorResumeNext onComplete
onErrorReturn
指示响应式类型在遇到错误时发出指定Function返回的项.
private void onErrorReturn() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
emitter.onNext("A");
emitter.onNext("B");
emitter.onError(new Throwable("出错了"));
emitter.onNext("C");
}
}).onErrorReturn(new Function<Throwable, String>() {
//通过此函数,将错误通知转换为想要的类型
@Override
public String apply(Throwable throwable) throws Throwable {
return "**Sky**";
}
})
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull String s) {
Log.i(TAG, "onErrorReturn onNext: " + s);
}
@Override
public void onError(@NonNull Throwable e) {
Log.i(TAG, "onErrorReturn onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.i(TAG, "onErrorReturn onComplete" );
}
});
}
输出:
5463-5463/com.sky.rxjava I/sky>>>: onErrorReturn onNext: A
5463-5463/com.sky.rxjava I/sky>>>: onErrorReturn onNext: B
5463-5463/com.sky.rxjava I/sky>>>: onErrorReturn onNext: **Sky**
5463-5463/com.sky.rxjava I/sky>>>: onErrorReturn onComplete
onErrorReturnItem
指示反应类型在遇到错误时发出特定项
private void onErrorReturnItem() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
emitter.onNext("A");
emitter.onNext("B");
emitter.onError(new Throwable("出错了"));
emitter.onNext("C");
}
}).onErrorReturnItem("~sky~")//收到错误通知时,转换为发出 此项,并发出完成通知
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull String s) {
Log.i(TAG, "onErrorReturnItem onNext: " + s);
}
@Override
public void onError(@NonNull Throwable e) {
Log.i(TAG, "onErrorReturnItem onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.i(TAG, "onErrorReturnItem onComplete" );
}
});
}
输出:
6151-6151/com.sky.rxjava I/sky>>>: onErrorReturnItem onNext: A
6151-6151/com.sky.rxjava I/sky>>>: onErrorReturnItem onNext: B
6151-6151/com.sky.rxjava I/sky>>>: onErrorReturnItem onNext: ~sky~
6151-6151/com.sky.rxjava I/sky>>>: onErrorReturnItem onComplete
Retry
retry
不会将原始Observable的onError
通知传递给观察者,它会重新订阅这个Observable,再给它一次机会无错误地完成它的数据序列。Retry
总是传递onNext
通知给观察者,由于重新订阅,可能会造成数据项重复.
private void retry() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
emitter.onNext("A");
emitter.onNext("B");
emitter.onError(new Throwable("出错了"));
emitter.onNext("C");
}
}).retry()
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
Log.i(TAG, "retry: " + s);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Throwable {
Log.i(TAG, "retry onError: " + throwable.getMessage());
}
});
}
输出:
7651-7651/com.sky.rxjava I/sky>>>: retry: A
7651-7651/com.sky.rxjava I/sky>>>: retry: B
7651-7651/com.sky.rxjava I/sky>>>: retry: A
7651-7651/com.sky.rxjava I/sky>>>: retry: B
7651-7651/com.sky.rxjava I/sky>>>: retry: A
7651-7651/com.sky.rxjava I/sky>>>: retry: B
7651-7651/com.sky.rxjava I/sky>>>: retry: A
......
retry()
还支持传递long类型的参数,表示重试的次数,如果在重试次数用尽,还没成功结束,则将最后一次的onError
发出.
retry()
也支持传递一个 Predicate用以控制某个错误通知 是否进行重新订阅.
retryUntil
通过指定的函数接口,判断是否对错误通知进行重试,直到这个函数接口返回true.就不再重新订阅,当函数接口返回true时,还未成功结束,就将最后一次订阅的onError()
发出
private void retryUntil() {
final int[] i = {0};
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
emitter.onNext("A");
emitter.onNext("B");
emitter.onError(new Throwable("出错了"));
emitter.onNext("C");
}
})
.retryUntil(new BooleanSupplier() {
@Override
public boolean getAsBoolean() throws Throwable {
//每次接收到错误时,如果重新订阅次数小于3次,就返回false 重新订阅,并且次数+1
//大于3次时,就返回true不再重新订阅,并将最后一次onError发出
if (i[0] > 3) {
return true;
}
i[0]++;
return false;
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
Log.i(TAG, "retryUntil: " + s);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Throwable {
Log.i(TAG, "retryUntil onError: " + throwable.getMessage());
}
});
}
输出:
8827-8827/com.sky.rxjava I/sky>>>: retryUntil: A
8827-8827/com.sky.rxjava I/sky>>>: retryUntil: B
8827-8827/com.sky.rxjava I/sky>>>: retryUntil: A
8827-8827/com.sky.rxjava I/sky>>>: retryUntil: B
8827-8827/com.sky.rxjava I/sky>>>: retryUntil: A
8827-8827/com.sky.rxjava I/sky>>>: retryUntil: B
8827-8827/com.sky.rxjava I/sky>>>: retryUntil: A
8827-8827/com.sky.rxjava I/sky>>>: retryUntil: B
8827-8827/com.sky.rxjava I/sky>>>: retryUntil onError: 出错了
retryWhen
将所有的错误通知传递给一个Observable,以确定是否重新订阅,以及重新订阅的时间.
通过Function 函数接口,返回一个Observable,这个Observable有几项,就表示需要重试几次,而每项发出的时间,就是重试的时间.
private void retryWhen() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
emitter.onNext("A");
emitter.onNext("B");
emitter.onError(new Throwable("出错了"));
emitter.onNext("C");
}
})
.retryWhen(new Function<Observable<Throwable>, ObservableSource<Long>>() {
@Override
public ObservableSource<Long> apply(Observable<Throwable> throwableObservable) throws Throwable {
//这里从0开始 每隔2秒发送一项,一共法发送3项,最后看输出结果,重试了3次,
//加上原来一次,一共订阅4次,并且重试每次间隔就是我们设置的2秒
//这里的 throwableObservable 里面包含我们所有的OnError信息,原始的和重试的.可以使用一个观察者订阅它就可以观察它的内容
return Observable.intervalRange(0,3,0,2, TimeUnit.SECONDS);
}
})
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull String s) {
Log.i(TAG, "retryWhen onNext: " + s);
}
@Override
public void onError(@NonNull Throwable e) {
Log.i(TAG, "retryWhen onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.i(TAG, "retryWhen onComplete" );
}
});
}