一、简介
Rxjava是基于事件流调用的方式来实现异步的库,它最大的特点就是哪怕逻辑很复杂,依然能保持简洁和优雅。异步操作很关键的一点是程序的简洁性,因为在调度过程比较复杂的情况下,异步代码经常会既难写也难被读懂。其原理是一种扩展的观察者模式。这里有四个角色:
被观察者(Observable) ==> 产生事件
观察者(Observer) ==> 接收事件,并给出响应动作
订阅(Subscribe) ==> 连接被观察者和观察者
事件(Event) ==> 被观察者 & 观察者 沟通的载体
二、基本使用
Observable.create(new ObservableOnSubscribe<Integer>() {
// 1. 创建被观察者 & 生产事件
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
}).subscribe(new Observer<Integer>() {
// 2. 通过通过订阅(subscribe)连接观察者和被观察者
// 3. 创建观察者 & 定义响应事件的行为
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
// 默认最先调用复写的 onSubscribe()
@Override
public void onNext(Integer value) {
Log.d(TAG, "对Next事件"+ value +"作出响应" );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
此外,被观察者 Observable的subscribe()具备多个重载的方法
// 表示观察者不对被观察者发送的事件作出任何响应(但被观察者还是可以继续发送事件)
public final Disposable subscribe() {}
// 表示观察者只对被观察者发送的Next事件作出响应
public final Disposable subscribe(Consumer<? super T> onNext) {}
// 表示观察者只对被观察者发送的Next事件 & Error事件作出响应
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) {}
// 表示观察者只对被观察者发送的Next事件、Error事件 & Complete事件作出响应
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete) {}
// 表示观察者只对被观察者发送的Next事件、Error事件 、Complete事件 & onSubscribe事件作出响应
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
Action onComplete, Consumer<? super Disposable> onSubscribe) {}
// 表示观察者对被观察者发送的任何事件都作出响应
public final void subscribe(Observer<? super T> observer) {}
可采用 Disposable.dispose() 切断观察者 与 被观察者 之间的连接
即观察者 无法继续 接收 被观察者的事件,但被观察者还是可以继续发送事件。
// 主要在观察者 Observer中 实现
Observer<Integer> observer = new Observer<Integer>() {
// 1. 定义Disposable类变量
private Disposable mDisposable;
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
// 2. 对Disposable类变量赋值
mDisposable = d;
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "对Next事件"+ value +"作出响应" );
if (value == 2) {
// 设置在接收到第二个事件后切断观察者和被观察者的连接
mDisposable.dispose();
Log.d(TAG, "已经切断了连接:" + mDisposable.isDisposed());
}
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
};
三、创建操作符
1、create
// 1. 通过creat()创建被观察者对象
Observable.create(new ObservableOnSubscribe<Integer>() {
// 2. 在复写的subscribe()里定义需要发送的事件
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onComplete();
} // 至此,一个被观察者对象(Observable)就创建完毕
}).subscribe(new Observer<Integer>() {
// 3. 通过通过订阅(subscribe)连接观察者和被观察者
// 4. 创建观察者 & 定义响应事件的行为
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
2、快捷创建操作符just
// 1. 创建时传入整型1、2、3
// 在创建后就会发送这些对象,相当于执行了onNext(1)、onNext(2)、onNext(3)、onComplete
Observable.just(1, 2, 3)
// 2. 通过通过订阅(subscribe)连接观察者和被观察者
// 3. 创建观察者 & 定义响应事件的行为
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
3、发送一个数组fromArray()
// 1. 设置需要传入的数组
Integer[] items = { 0, 1, 2, 3, 4 };
// 2. 创建被观察者对象(Observable)时传入数组
// 在创建后就会将该数组转换成Observable & 发送该对象中的所有数据
Observable.fromArray(items)
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
4、发送一个集合fromIterable()
// 1. 设置一个集合
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
// 2. 通过fromIterable()将集合中的对象 / 数据发送出去
Observable.fromIterable(list)
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
5、延迟创建defer()
// 第一次赋值
Integer i = 10;
// 2. 通过defer 定义被观察者对象
// 注:此时被观察者对象还没创建
Observable<Integer> observable = Observable.defer(new Callable<ObservableSource<? extends Integer>>() {
@Override
public ObservableSource<? extends Integer> call() throws Exception {
return Observable.just(i);
}
});
// 第二次赋值
i = 15;
// 注:此时,才会调用defer()创建被观察者对象(Observable)
observable.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Integer value) {
// value结果是15
Log.d(TAG, "接收到的整数是"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
6、延迟发送timer()
// 延迟2s后,发送一个long=0类型数值
// 注:timer操作符默认运行在一个新线程上
Observable.timer(2, TimeUnit.SECONDS)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Long value) {
Log.d(TAG, "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
7、定时发送事件interval
// 参数说明:
// 参数1 = 第1次延迟时间;
// 参数2 = 间隔时间数字;
// 参数3 = 时间单位;
Observable.interval(3,1,TimeUnit.SECONDS)
// 该例子发送的事件序列特点:延迟3s后发送事件,每隔1秒产生1个数字(从0开始递增1,无限个)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
// 默认最先调用复写的 onSubscribe()
@Override
public void onNext(Long value) {
Log.d(TAG, "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
8、定时发送事件intervalRange
// 参数说明:
// 参数1 = 事件序列起始点;
// 参数2 = 事件数量;
// 参数3 = 第1次事件延迟发送时间;
// 参数4 = 间隔时间数字;
// 参数5 = 时间单位
Observable.intervalRange(3,10,2, 1, TimeUnit.SECONDS)
// 该例子发送的事件序列特点:
// 1. 从3开始,一共发送10个事件;
// 2. 第1次延迟2s发送,之后每隔2秒产生1个数字(从0开始递增1,无限个)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Long value) {
Log.d(TAG, "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
9、无延迟发送事件range
// 参数说明:
// 参数1 = 事件序列起始点;
// 参数2 = 事件数量;
// 注:若设置为负数,则会抛出异常
Observable.range(3,10)
// 该例子发送的事件序列特点:从3开始发送,每次发送事件递增1,一共发送10个事件
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
// 默认最先调用复写的 onSubscribe()
@Override
public void onNext(Integer value) {
Log.d(TAG, "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
四、变换操作符
1、map变换操作符
对被观察者发送的每1个事件都通过 指定的函数处理,从而变换成另外一种事件
Observable.create(new ObservableOnSubscribe<Integer>() {
// 1. 被观察者发送事件 = 参数为整型 = 1、2、3
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
// 2. 使用Map变换操作符中的Function函数对被观察者发送的事件进行统一变换:整型变换成字符串类型
}).map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return "使用 Map变换操作符 将事件" + integer +"的参数从 整型"+integer + " 变换成 字符串类型" + integer ;
}
}).subscribe(new Consumer<String>() {
// 3. 观察者接收事件时,是接收到变换后的事件 = 字符串类型
@Override
public void accept(String s) throws Exception {
Log.d(TAG, s);
}
});
2、flatMap变换操作符
将被观察者发送的事件序列进行拆分 & 单独转换,再合并成一个新的事件序列,最后再进行发送
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
// 采用flatMap()变换操作符
}).flatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Exception {
final List<String> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add("我是事件 " + integer + "拆分后的子事件" + i);
// 通过flatMap中将被观察者生产的事件序列先进行拆分,再将每个事件转换为一个新的发送三个String事件
}
// 所有事件最终合并成Observable后才会发送给观察者。
return Observable.fromIterable(list);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, s);
}
});
// 结果如下:
我是事件3拆分后的子事件0
我是事件2拆分后的子事件0
我是事件2拆分后的子事件1
我是事件2拆分后的子事件2
我是事件3拆分后的子事件1
我是事件3拆分后的子事件2
我是事件1拆分后的子事件0
我是事件1拆分后的子事件1
我是事件1拆分后的子事件2
3、contactMap变换操作符
和flatMap一样,只是contactMap保证了输入和输出的顺序。如果使用了contactMap,那么顺序如下:
我是事件1拆分后的子事件0
我是事件1拆分后的子事件1
我是事件1拆分后的子事件2
我是事件2拆分后的子事件0
我是事件2拆分后的子事件1
我是事件2拆分后的子事件2
我是事件3拆分后的子事件0
我是事件3拆分后的子事件1
我是事件3拆分后的子事件2
4、Buffer变换操作符
定期从 被观察者(Obervable)需要发送的事件中 获取一定数量的事件 & 放到缓存区中,最终发送。
// 被观察者 需要发送5个数字
Observable.just(1, 2, 3, 4, 5)
.buffer(3, 1) // 设置缓存区大小 & 步长。缓存区大小 = 每次从被观察者中获取的事件数量。步长 = 每次获取新事件的数量
.subscribe(new Observer<List<Integer>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(List<Integer> stringList) {
Log.d(TAG, " 缓存区里的事件数量 = " + stringList.size());
for (Integer value : stringList) {
Log.d(TAG, " 事件 = " + value);
}
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应" );
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
五、组合/并发操作符
1、contact
组合多个被观察者一起发送数据,合并后按发送顺序串行执行
// concat():组合多个被观察者(≤4个)一起发送数据
// 注:串行执行
Observable.concat(Observable.just(1, 2, 3),
Observable.just(4, 5, 6),
Observable.just(7, 8, 9),
Observable.just(10, 11, 12))
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
结果如下:
接收到了事件1
接收到了事件2
接收到了事件3
接收到了事件4
接收到了事件5
接收到了事件6
接收到了事件7
接收到了事件8
接收到了事件9
接收到了事件10
接收到了事件11
接收到了事件12
对Complete事件作出响应
2、concatArray
和1中的concat没有区别,仅仅只是concatArray可以发送大于4个的事件流
3、merge
组合多个被观察者一起发送数据,合并后按时间线并行执行
区别上述concat()操作符:同样是组合多个被观察者一起发送数据,但concat()操作符合并后是按发送顺序串行执行
Observable.merge(
// 从0开始发送、共发送3个数据、第1次事件延迟发送时间 = 1s、间隔时间 = 1s
Observable.intervalRange(0, 3, 1, 1, TimeUnit.SECONDS),
// 从2开始发送、共发送3个数据、第1次事件延迟发送时间 = 1s、间隔时间 = 1s
Observable.intervalRange(2, 3, 1, 1, TimeUnit.SECONDS))
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Long value) {
Log.d(TAG, "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
结果如下:
接收到了事件0
接收到了事件2
接收到了事件1
接收到了事件3
接收到了事件2
接收到了事件4
4、zip
合并 多个被观察者(Observable)发送的事件,生成一个新的事件序列(即组合过后的事件序列),并最终发送。
事件组合方式 = 严格按照原先事件序列 进行对位合并
最终合并的事件数量 = 多个被观察者(Observable)中数量最少的数量
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
}).subscribeOn(Schedulers.io()); // 设置被观察者1在工作线程1中工作
Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("A");
Thread.sleep(1000);
emitter.onNext("B");
Thread.sleep(1000);
emitter.onNext("C");
Thread.sleep(1000);
emitter.onNext("D");
Thread.sleep(1000);
emitter.onComplete();
}
}).subscribeOn(Schedulers.newThread());// 设置被观察者2在工作线程2中工作
// 假设不作线程控制,则该两个被观察者会在同一个线程中工作,即发送事件存在先后顺序,而不是同时发送
// 注:创建BiFunction对象传入的第3个参数 = 合并后数据的数据类型
Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
@Override
public String apply(Integer integer, String string) throws Exception {
return "@@@" + integer + string + "@@@";
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe");
}
@Override
public void onNext(String value) {
Log.d(TAG, "最终接收到的事件 = " + value);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError");
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
}
});
D/zhangbh: onSubscribe
D/zhangbh: 最终接收到的事件 = @@@1A@@@
D/zhangbh: 最终接收到的事件 = @@@2B@@@
D/zhangbh: 最终接收到的事件 = @@@3C@@@
D/zhangbh: onComplete
六、线程切换/调度
Schedulers.immediate() ==> 当前线程 = 不指定线程(默认)
AndroidSchedulers.mainThread() ==>Android主线程
Schedulers.newThread() ==> 常规新线程 (耗时等操作)
Schedulers.io() ==> io操作线程、网络请求、读写文件等io密集型操作
Schedulers.computation() ==> CPU计算操作线程(大量计算操作)
1、subscribeOn,指定被观察者发送事件的线程
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
// 执行在io线程
Log.i(TAG, "==create==" + Thread.currentThread().getName());
e.onNext(1);
}
// 指定被观察者执行在io线程
}).subscribeOn(Schedulers.io())
// 这个指定无效,subscribeOn只有第一个设置的线程有效
.subscribeOn(Schedulers.newThread())
.doOnSubscribe(new Consumer<Disposable>() {
@Override
public void accept(Disposable disposable) throws Exception {
// 执行在主线程
Log.i(TAG, "==doOnSubscribe==" + Thread.currentThread().getName());
}
// 指定doOnSubscribe执行在主线程
}).subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "接收到了事件" + value);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
订阅成功后,先执行doOnSubscribe的回调,这个时候就看有没有使用subscribeOn指定其执行线程,如果没有,那么就默认使用当前订阅所处的线程。如果有,像上例子,那么就使用主线程执行这个回调。接着需要执行被观察者的发送,依然看有没有通过subscribeOn指定线程,如果没有,这个时候会使用doOnSubscribe后的subscribeOn设置的线程。如果有,那当然就用自己设置的。此外,多次设置subscribeOn,只有第一次有效。
2、observeOn,指定观察者 接收 & 响应事件的线程
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
// 执行在io线程
Log.i(TAG, "==create==" + Thread.currentThread().getName());
e.onNext(1);
}
// 指定被观察者Observable执行在io线程
}).subscribeOn(Schedulers.io())
// 指定观察者doOnNext执行在newThread
.observeOn(Schedulers.newThread())
// 指定观察者doOnNext执行在io
.observeOn(Schedulers.io())
.doOnNext(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
// 由于observeOn多次切换都有效,所以最终这里会执行在io线程
Log.i(TAG, "==doOnNext==" + Thread.currentThread().getName());
}
// 指定观察者Observer执行在主线程
}).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "接收到了事件" + value);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
七、do相关操作符
1、doOnNext()
发送next事件时,最晚在观察者执行onNext前调用,属于观察者,所以使用observeOn切换线程。
2、doAfterNext()
发送next事件时,在观察者执行onNext后调用,属于观察者,所以使用observeOn切换线程。
3、doOnError()
发送error事件时,最晚在观察者执行onError前调用,属于观察者,所以使用observeOn切换线程。
4、doOnComplete()
发送complete事件时,最晚在观察者执行onComplete前调用,属于观察者,所以使用observeOn切换线程。
5、doOnEach()
发送任何事件,都会调用此方法,属于观察者,所以使用observeOn切换线程。
6、doFinally()
所有事件的最后执行,比观察者的执行onComplete还晚,属于观察者,所以使用observeOn切换线程。
7、doOnSubscribe()
观察者订阅的时候被调用,优先于被观察者的发送,属于被观察者,所以使用subscribeOn切换线程。
8、doOnDispose()
观察者取消订阅时调用,属于观察者,所以使用observeOn切换线程。
八、错误处理
1、onErrorReturn
遇到错误时,发送1个特殊事件 & 正常终止
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onError(new Throwable("发生错误了"));
}
})
.onErrorReturn(new Function<Throwable, Integer>() {
@Override
public Integer apply(@NonNull Throwable throwable) throws Exception {
// 捕捉错误异常
Log.e(TAG, "在onErrorReturn处理了错误: "+throwable.toString() );
return 666;
// 发生错误事件后,发送一个"666"事件,最终正常结束
}
})
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
接收到了事件1
接收到了事件2
在onErrorReturn处理了错误: java.lang.Throwable : 发生错误了
接收到了事件666
对Complete事件作出响应
2、retry
1、重试,即当出现错误时,让被观察者(Observable)重新发射数据
2、接收到 onError()时,重新订阅 & 发送事件
3、Throwable 和 Exception都可拦截
九、过滤操作符
1、filter
过滤 特定条件的事件
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
// 1. 发送5个事件
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onNext(4);
emitter.onNext(5);
}
// 2. 采用filter()变换操作符
}).filter(new Predicate<Integer>() {
// 根据test()的返回值 对被观察者发送的事件进行过滤 & 筛选
// a. 返回true,则继续发送
// b. 返回false,则不发送(即过滤)
@Override
public boolean test(Integer integer) throws Exception {
return integer > 3;
// 本例子 = 过滤了整数≤3的事件
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "过滤后得到的事件是:"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
2、take
指定观察者最多能接收到的事件数量
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
// 1. 发送5个事件
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onNext(4);
emitter.onNext(5);
}
// 采用take()变换操作符
// 指定了观察者只能接收2个事件
}).take(2)
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "过滤后得到的事件是:"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
3、takeLast
和take差不多,指定观察者只能接收到被观察者发送的最后几个事件
4、throttleFirst和throttleLast
在某段时间内,只发送该段时间内第1次事件 / 最后1次事件
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
// 隔段事件发送时间
e.onNext(1);
Thread.sleep(500);
e.onNext(2);
Thread.sleep(400);
e.onNext(3);
Thread.sleep(300);
e.onNext(4);
Thread.sleep(300);
e.onNext(5);
Thread.sleep(300);
e.onNext(6);
Thread.sleep(400);
e.onNext(7);
Thread.sleep(300);
e.onNext(8);
Thread.sleep(300);
e.onNext(9);
Thread.sleep(300);
e.onComplete();
}
}).throttleFirst(1, TimeUnit.SECONDS)//每1秒中采用第一次的事件数据
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
开始采用subscribe连接
接收到了事件1
接收到了事件4
接收到了事件7
对Complete事件作出响应
5、throttleWithTimeout
发送数据事件时,若2次发送事件的间隔<指定时间,就会丢弃前一次的数据,直到指定时间内都没有新数据发射时才会发送后一次的数据。
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
// 隔段事件发送时间
e.onNext(1);
Thread.sleep(500);
e.onNext(2); // 1和2之间的间隔小于指定时间1s,所以前1次数据(1)会被抛弃,2会被保留
Thread.sleep(1500); // 因为2和3之间的间隔大于指定时间1s,所以之前被保留的2事件将发出
e.onNext(3);
Thread.sleep(1500); // 因为3和4之间的间隔大于指定时间1s,所以3事件将发出
e.onNext(4);
Thread.sleep(500); // 因为4和5之间的间隔小于指定时间1s,所以前1次数据(4)会被抛弃,5会被保留
e.onNext(5);
Thread.sleep(500); // 因为5和6之间的间隔小于指定时间1s,所以前1次数据(5)会被抛弃,6会被保留
e.onNext(6);
Thread.sleep(1500); // 因为6和Complete实践之间的间隔大于指定时间1s,所以之前被保留的6事件将发出
e.onComplete();
}
}).throttleWithTimeout(1, TimeUnit.SECONDS)//每1秒中采用数据
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
接收到了事件2
接收到了事件3
接收到了事件6
对Complete事件作出响应
十、布尔操作符
1、all
判断发送的每项数据是否都满足设置的函数条件,若都满足,才能往下走。
2、takeWhile
判断某项数据是否满足设置的函数条件,满足的项才能往下走。
3、skipWhile
当某项==false时,才能往下走,和takeWhile相反。
4、takeUntil
// 1. 每1s发送1个数据 = 从0开始,递增1,即0、1、2、3
Observable.interval(1, TimeUnit.SECONDS)
// 2. 通过takeUntil的Predicate传入判断条件
.takeUntil(new Predicate<Long>(){
@Override
public boolean test( Long integer) throws Exception {
return (integer>3);
// 返回true时,就停止发送事件
// 当发送的数据满足>3时,就停止发送Observable的数据
}
}).subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Long value) {
Log.d(TAG,"发送了事件 "+ value);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});