一个实现异步操作的库。RxJava 的异步实现,是通过一种扩展的观察者模式来实现的。
RxJava观察者模式
两个对象观察者与被观察者,其中观察者与被观察者建立了订阅关系,如果被观察者发生了变化那么需要及时通知观察者,观察者收到通知后做出相应的处理.。
例子: 顾客去买蛋糕这样一个场景(把顾客和蛋糕店店员分别看做观察者与被观察者),由于蛋糕是现做需要一定时间才能完成,顾客在购买时一般会先付钱给店员拿到一个付款凭证后离开去忙其他事,这样他们就建立了购买关系(建立订阅关系),店员在做完蛋糕后(被观察者发生变化),店员就会通知顾客来拿(消息通知到观察者),顾客在收到店员通知后前来拿蛋糕(观察者收到通知后做出相应的处理)。
基本概念
被观察者
1.Observable
在观察者模式中称为“被观察者”,它决定什么时候触发事件以及触发怎样的事件。
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();
}
})
ObservableEmitter(发射器)用来发出事件,调用emitter的onNext(T value)、onComplete()、onError(Throwable error) 分别发出next事件、complete事件和error事件.。
2.Flowable
Flowable里默认有一个大小为128存储空间 (处于异步线程) 适用于:发送方数据发送量非常多,而处理方来不及处理造成内存溢出问题。
Flowable<Integer> upstream = Flowable.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
Log.d(TAG, "emit 1");
emitter.onNext(1);
Log.d(TAG, "emit 2");
emitter.onNext(2);
Log.d(TAG, "emit 3");
emitter.onNext(3);
Log.d(TAG, "emit complete");
emitter.onComplete();
}
}, BackpressureStrategy.ERROR); //增加了一个参数
Subscriber<Integer> downstream = new Subscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
Log.d(TAG, "onSubscribe");
s.request(Long.MAX_VALUE); //注意这句代码
}
@Override
public void onNext(Integer integer) {
Log.d(TAG, "onNext: " + integer);
}
@Override
public void onError(Throwable t) {
Log.w(TAG, "onError: ", t);
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
}
};
upstream.subscribe(downstream);
注解: 创建Flowable的时候增加了一个参数, 这个参数是用来选择背压的,处理数据太多造成的OOM异常。
可选的背压策略
- BackpressureStrategy.ERROR 直接抛出一个异常
- BackpressureStrategy.DROP 直接把存不下的事件丢弃
- BackpressureStrategy.LATEST 只保留最新的事件
观察者
1. Observer
观察者模式中的“观察者”,可接收Observable发送的数据
Observer<String> observer = new Observer<String>() {
@Override public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String aLong) {
//观察者接收到通知,进行相关操作
}
@Override public void onError(Throwable e) {
}
@Override public void onComplete() {
}
};
- onSubscribe()
传递参数为Disposable,Disposable相当于Subscription,用于解除订阅。 - onNext()
处理事件。将要处理的事件添加到事件队列中。 - onError()
事件队列异常。在事件处理过程中出现异常时,onError() 会被触发,同时队列自动终止,不允许再有事件发出。 - onComplete()
事件队列完结时调用该方法。RxJava 不仅把每个事件单独处理,还会把它们看做一个队列。 - Disposable (一次性用品)
Disposable的作用是切断连接,是将Observer(观察者)切断,不再接收来自被观察者的事件,而被观察者的事件却仍在继续执行。
2.Consumer
Observable.just("hello").subscribe(
new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
System.out.println(s);
}
});
Consumer中的accept()方法接收一个来自Observable的单个值
整体订阅流程
订阅,观察者与被观察者,通过subscribe()方法进行订阅。
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();
}
}).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");
}
});
由被观察者调用了观察者的回调方法,就实现了由被观察者向观察者的事件传递,即观察者模式。
规则
- Observable可以发送无限个onNext,Observer可以接收无限个onNext.
- Observable发送了一个onComplete后,之后的事件将会继续发送.Observer收到onComplete事件之后将不再继续接收事件.
- Observable发送了一个onError后,onError之后的事件将继续发送.Observer收到onError事件之后将不再继续接收事件.
- Observable可以不发送onComplete或onError.
- onComplete和onError必须唯一并且互斥. 即不能发多个onComplete, 也不能发多个onError, 也不能先发一个onComplete, 然后再发一个onError.
Obsesrver用于订阅Observable,而Subscriber用于订阅Flowable
Scheduler 线程调度器
在不指定线程的情况下, RxJava 遵循的是线程不变的原则,即:在哪个线程调用 subscribe(),就在哪个线程生产事件;在哪个线程生产事件,就在哪个线程消费事件.如果需要切换线程,就需要用到Scheduler (调度器)。在RxJava 中,Scheduler(相当于线程控制器) RxJava 通过它来指定每一段代码应该运行在什么样的线程。
- subscribeOn():指定Observable(被观察者)所在的线程,或者叫做事件产生的线程(改变调用它之前代码的线程)
- observeOn():指定 Observer(观察者)所运行在的线程,或者叫做事件消费的线程(改变调用它之后代码的线程)
注意:
- 多次调用subscribeOn() 只有第一次的有效, 其余的会被忽略.
- 多次指定是Observer线程是可以的,每调用一次observeOn(),Observer的线程就会切换一次。
线程选项
- Schedulers.io()
I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的Scheduler。io()的内部实现是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下io() 比newThread() 更有效率。
- Schedulers.computation()
计算所用的Scheduler,例如图形的计算。这个Scheduler使用固定线程池,大小为cpu核数。不要把I/O操作放在computation() 中,否则I/O 操作的等待时间会浪费CPU。它是buffer、debounce、delay、interval、sample和skip 操作符的默认调度器。
- Schedulers.newThread()
总是启用新线程,并在新线程执行操作
- Schedulers.trampoline
当我们想在当前线程执行一个任务时,并不是立即时,可以用
trampoline()将它入列。这个调度器将会处理它的队列并且按序运行队列的每一个任务。它是repeat 和retry 操作符默认的调度器。
- AndroidSchedulers.mainThread()
代表Android的主线程
常见操作符
创建操作符
just(T…)
Observable observable = Observable.just("Hello", "Hi", "Aloha");
创建一个Observable并自动调用onNext( )发射数据。通过just()方式 直接触发onNext(),just中传递的参数将直接在Observer的onNext()方法中接收到。
fromIterable(Iterable<? extends T>)
List<String> list = new ArrayList<String>();
for(int i =0;i<10;i++){
list.add("Hello"+i);
}
Observable<String> observable = Observable.fromIterable((Iterable<String>) list);
使用fromIterable(),遍历集合,发送每个item。相当于多次回调onNext()方法,每次传入一个item。
from(T[ ]) / from(Iterable<? extends T>)
String[] words = {"Hello", "Hi", "Aloha"};
Observable observable = Observable.from(words);
传入的数组或 Iterable 拆分成具体对象后,依次发送出来
defer()
Observable<String> observable = Observable.defer(new Callable<ObservableSource<? extends String>>() {
@Override
public ObservableSource<? extends String> call() throws Exception
return Observable.just("hello");
}
});
interval()
创建一个按固定时间间隔发射整数序列的Observable,相当于定时器。
// 发送1到20的数。即调用20次nNext()方法,依次传入1-20数字
Observable<String> observable = Observable.interval(2, TimeUnit.SECONDS);
第一个参数:起始值;第二个参数:发送的个数(0:不发送,负数:抛异常)
timer()
Observable<Integer> observable = Observable.timer(2, TimeUnit.SECONDS);
创建一个Observable,它在一个给定的延迟后发射一个特殊的值,即表示延迟2秒后,调用onNext()方法
repeat()
Observable<Integer> observable = Observable.just(123).repeat();
创建一个N次重复发射特定数据的Observable。
range()
Observable.range(0,5)
.subscribe(i->{
Log.e("rangeOperation","---->"+i);
});
执行结果:
rangeOperation: ---->0
rangeOperation: ---->1
rangeOperation: ---->2
rangeOperation: ---->3
rangeOperation: ---->4
创建发射指定范围的序列的Observable,发射一个范围内的有序序列。第一个参数是起始值,并且不小于0;第二个参数为整数序列的个数。
辅助操作符
doOnNext
允许我们在每次输出一个元素之前做一些额外的事情
Observable.just(list).flatMap(new Function<List<String>, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(List<String> strings) throws Exception {
return Observable.fromIterable(strings);
}
}).take(5).doOnNext(new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {
System.out.println("准备工作");
}
}).subscribe(new Consumer<Object>() {
@Override
public void accept(Object s) throws Exception {
System.out.println((String)s);
}
});
timeout
如果原始Observablev过了指定的一段时长没有发射任何数据,timeout 操作符会一个onError 通知终止了这个Observable ,或者继续执行一个备用的Observable。它默认在computation调度器上执行。
Observable.create(new io.reactivex.rxjava3.core.ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(io.reactivex.rxjava3.core.@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
for (int i=0;i<10;i++){
Thread.sleep(i*100);
emitter.onNext(i);
}
emitter.onComplete();
}
}).timeout(200,TimeUnit.MILLISECONDS).subscribe(new io.reactivex.rxjava3.functions.Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG,"-timeoutOperation---->"+integer);
}
}, new io.reactivex.rxjava3.functions.Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Throwable {
Log.e(TAG,"-timeoutOperation---异常->"+throwable.getMessage());
}
});
执行结果:
RxActivity: -timeoutOperation---->0
RxActivity: -timeoutOperation---->1
RxActivity: -timeoutOperation---异常->The source did not signal an event for 200 milliseconds and has been terminated.
上面发射的数据,如果超过了200ms,就会抛出异常
subscribeOn、observeOn
subscribeOn 操作符用于指定Observable自身在哪个线程上运行。如果Observable需要执行耗时操作,一般可以让其在新开的一个子线程上运行。observeOn用来指定Observable所运行的线程,也就是发射出的数据在哪个线程上使用。一般情况下会指定在主线程中运行。
Observable.create(new io.reactivex.rxjava3.core.ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(io.reactivex.rxjava3.core.@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
Log.e(TAG,"被观察者:"+Thread.currentThread().getName());
emitter.onNext(1);
emitter.onComplete();
}
}).subscribeOn(io.reactivex.rxjava3.schedulers.Schedulers.newThread())
.observeOn(io.reactivex.rxjava3.android.schedulers.AndroidSchedulers.mainThread())
.subscribe(new io.reactivex.rxjava3.functions.Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG,"观察者:"+Thread.currentThread().getName());
}
});
执行结果:
RxActivity: 被观察者:RxNewThreadScheduler-1
RxActivity: 观察者:main
连接操作符
通过连接操作符,将多个被观察数据(数据源)连接在一起
startWith
可作用于Flowable、Observable。将指定数据源合并在另外数据源的开头。
Observable<String> source1 = Observable.just("Hello", "World");
Observable<String> source2 = Observable.just("Internet", "I","Love");
source1.startWith(source2).subscribe(s -> {
Log.e("funStartWith","---->"+s);
});
打印数据:
funStartWith: ---->Internet
funStartWith: ---->I
funStartWith: ---->Love
funStartWith: ---->Hello
funStartWith: ---->World
变换操作符
变换操作符作用是对Observable发射的数据按照一定规则做一些变换操作,然后将变换后的数据发射出去。
Map
map 操作符通过指定一个Func对象,将Observable 转换为一个新的Observable并发射,观察者将收到新的Observable处理。
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
}).map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
Log.e(TAG, "----数据类型转换进行中--->" + integer);
return String.valueOf(integer);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.e(TAG, "----数据类型转换后结果--->" + s);
}
});
执行结果:
RxActivity: ----数据类型转换进行中--->1
RxActivity: ----数据类型转换后结果--->1
RxActivity: ----数据类型转换进行中--->2
RxActivity: ----数据类型转换后结果--->2
RxActivity: ----数据类型转换进行中--->3
RxActivity: ----数据类型转换后结果--->3
FlatMap
将一个发送事件的Observable变换为多个发送事件的Observables,然后将它们发射的事件合并后放进一个单独的Observable里。注意: flatMap并不保证事件的顺序。
List<Integer> list = Arrays.asList(1, 2, 3);
io.reactivex.Observable.fromIterable(list).flatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer num) throws Exception {
List<String> numList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
numList.add("第" + num + "人" + "领取了第" + i + "任务");
Log.e(TAG, "第" + num + "人 所在线程--------->" + Thread.currentThread().getName());
}
return io.reactivex.Observable.fromIterable(numList).delay(20, TimeUnit.MILLISECONDS);
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.e(TAG, "-------->" + s + "----所处线程-->" + Thread.currentThread().getName());
}
});
执行结果:
RxActivity: 第1人 所在线程--------->RxCachedThreadScheduler-1
RxActivity: 第1人 所在线程--------->RxCachedThreadScheduler-1
RxActivity: 第1人 所在线程--------->RxCachedThreadScheduler-1
RxActivity: 第2人 所在线程--------->RxCachedThreadScheduler-1
RxActivity: 第2人 所在线程--------->RxCachedThreadScheduler-1
RxActivity: 第2人 所在线程--------->RxCachedThreadScheduler-1
RxActivity: 第3人 所在线程--------->RxCachedThreadScheduler-1
RxActivity: 第3人 所在线程--------->RxCachedThreadScheduler-1
RxActivity: 第3人 所在线程--------->RxCachedThreadScheduler-1
RxActivity: -------->第2人领取了第0任务----所处线程-->main
RxActivity: -------->第2人领取了第1任务----所处线程-->main
RxActivity: -------->第2人领取了第2任务----所处线程-->main
RxActivity: -------->第1人领取了第0任务----所处线程-->main
RxActivity: -------->第1人领取了第1任务----所处线程-->main
RxActivity: -------->第1人领取了第2任务----所处线程-->main
RxActivity: -------->第3人领取了第0任务----所处线程-->main
RxActivity: -------->第3人领取了第1任务----所处线程-->main
RxActivity: -------->第3人领取了第2任务----所处线程-->main
flatMap 的合并允许交叉,也就是说可能交错地发送事件,最终结果的顺序可能并不是原始Observable发送时的顺序。
flatMapIterable
flatMapIterable操作符可以将数据包装成Iterable,在Iterable中就可以对数据进行处理
Observable.just(1,2,3).flatMapIterable((io.reactivex.rxjava3.functions.Function<Integer, Iterable<?>>) integer -> {
List<Integer> mList=new ArrayList<>();
mList.add(integer+1);
return mList;
}).subscribe(i->{
Log.e(TAG,"flatMapIterable"+i);
});
运算结果:
RxActivity: flatMapIterable2
RxActivity: flatMapIterable3
RxActivity: flatMapIterable4
ConcatMap
作用于Flowable、Observable、Maybe。将数据源的元素作用于指定函数后,将函数的返回值有序的存在新的数据源。注意:concatMap保证事件的顺序。
List<Integer> list = Arrays.asList(1, 2, 3);
io.reactivex.Observable.fromIterable(list).concatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer num) throws Exception {
List<String> numList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
numList.add("第" + num + "人" + "领取了第" + i + "任务");
}
return io.reactivex.Observable.fromIterable(numList).delay(20, TimeUnit.MILLISECONDS);
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.e(TAG, "-------->" + s + "----所处线程-->" + Thread.currentThread().getName());
}
});
执行结果:
RxActivity: -------->第1人领取了第0任务----所处线程-->main
RxActivity: -------->第1人领取了第1任务----所处线程-->main
RxActivity: -------->第1人领取了第2任务----所处线程-->main
RxActivity: -------->第2人领取了第0任务----所处线程-->main
RxActivity: -------->第2人领取了第1任务----所处线程-->main
RxActivity: -------->第2人领取了第2任务----所处线程-->main
RxActivity: -------->第3人领取了第0任务----所处线程-->main
RxActivity: -------->第3人领取了第1任务----所处线程-->main
RxActivity: -------->第3人领取了第2任务----所处线程-->main
它解决了flatMap交叉问题,提供了一种能够把发射的值连续在一起的函数,而不是合并它们。
concatMapDelayError
只是将过程发送的所有错误延迟到最后处理。
Observable.range(0, 5)
.concatMapDelayError(i -> {
if (i == 0) return Observable.error(new IOException("Number can not use"));
else return Observable.just(i * 2);
}).blockingSubscribe(i ->
Log.e("funConcatMapDelayError", "---->" + i),
e->Log.e("funConcatMapDelayError", "---->" + e.getMessage())
);
执行结果:
funConcatMapDelayError: ---->2
funConcatMapDelayError: ---->4
funConcatMapDelayError: ---->6
funConcatMapDelayError: ---->8
funConcatMapDelayError: ---->Number can not use
concatMapCompletable
Observable.just(2,3,4)
.concatMapCompletable(i->{
return Completable.timer(i,TimeUnit.SECONDS).doOnComplete(()->{
Log.e("funConcatMapCompletable","--->item_"+i);
});
}).doOnComplete(()->{
Log.e("funConcatMapCompletable","--->Complete");
}).blockingAwait();
执行结果:
funConcatMapCompletable: --->item_2
funConcatMapCompletable: --->item_3
funConcatMapCompletable: --->item_4
funConcatMapCompletable: --->Complete
concatMapCompletableDelayError
只是将过程发送的所有错误延迟到最后处理。
Observable.just(2,3,4)
.concatMapCompletableDelayError(i->{
if (i==3){
return Completable.error(new IOException("can not user "+i));
}else {
return Completable.timer(i,TimeUnit.SECONDS).doOnComplete(()->{
Log.e("funConcatMapCompletableError","--->item_"+i);
} );
}
})
.doOnError(err->{
Log.e("funConcatMapCompletableError","--->"+err.getMessage());
})
.onErrorComplete()
.blockingAwait();
执行结果:
funConcatMapCompletableError: --->item_2
funConcatMapCompletableError: --->item_4
funConcatMapCompletableError: --->can not user 3
buffer
作用于Flowable、Observable。将数据源拆解含有长度为n的多个数据源,不够n的成为一个数据源。
Observable.range(1,20).buffer(5).subscribe(list->{
Log.e("funBuffer","---->"+list);
});
执行结果:
funBuffer: ---->[1, 2, 3, 4, 5]
funBuffer: ---->[6, 7, 8, 9, 10]
funBuffer: ---->[11, 12, 13, 14, 15]
funBuffer: ---->[16, 17, 18, 19, 20]
cast
作用于Flowable、Observable、Maybe、Single。将数据元素转型成其他类型,转型失败会抛出异常。
Observable<? extends Number> source = Observable.just(1, 2.23, 5.0, 6, 7f);
source.filter(number ->
Integer.class.isInstance(number)
).cast(Integer.class).subscribe(number->
Log.e("funCast","---->"+number)
);
执行结果:
funCast: ---->1
funCast: ---->6
groupBy
Stu stu1=new Stu(1,"小米");
Stu stu2=new Stu(2,"小名");
Stu stu3=new Stu(3,"小李");
Observable.just(stu3,stu1,stu2).groupBy(new Function<Stu, Integer>() {
@Override
public Integer apply(Stu stu) throws Throwable {
return stu.getNum();
}
}).subscribe(new Consumer<GroupedObservable<Integer, Stu>>() {
@Override
public void accept(GroupedObservable<Integer, Stu> integerStuGroupedObservable) throws Throwable {
Log.e("groupByOperation","----->"+integerStuGroupedObservable.getKey());
}
});
执行结果:
groupByOperation: --->3
groupByOperation: --->1
groupByOperation: --->2
过滤操作符
Sample
sample(2, TimeUnit.SECONDS);//每隔2秒从Observable 取样,交给Observer去处理。
Filter
作用:对Observable产生的数据根据一定条件进行过滤,把过滤后的数据将加入到新的Observable对象中,传递给Observer想要的数据形式。
Observable.just(0,1,2,3,4,5,6)
.filter(s -> s%2==0)
.subscribe(s -> Log.e(TAG,"----filterOperation-->"+s));
执行结果:
RxActivity: ----filterOperation-->0
RxActivity: ----filterOperation-->2
RxActivity: ----filterOperation-->4
RxActivity: ----filterOperation-->6
skip
将源Observable发射的数据过滤掉前几项
Observable.just(0,1,2,3,4,5,6)
.skip(3).subscribe(s->
Log.e(TAG,"-skipOperation-->"+s)
);
执行结果:
RxActivity: -skipOperation-->3
RxActivity: -skipOperation-->4
RxActivity: -skipOperation-->5
RxActivity: -skipOperation-->6
elementAt
用来返回指定位置的数据
Observable.just(0,1,2,3,4,5,6)
.elementAt(3).subscribe(s->
Log.e(TAG,"-elementAtOperation-->"+s)
);
执行结果:
RxActivity: -elementAtOperation-->3
distinct
用来去重,其只允许还没有发射过的数据项通过。
Observable.just(0,1,1,3,4,3,6)
.distinct().subscribe(s->
Log.e(TAG,"-distinctOperation-->"+s)
);
执行结果:
RxActivity: -distinctOperation-->0
RxActivity: -distinctOperation-->1
RxActivity: -distinctOperation-->3
RxActivity: -distinctOperation-->4
RxActivity: -distinctOperation-->6
Take
将源Observable发射的数据取前几项
List<String> list=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
Observable.just(list).flatMap(new Function<List<String>, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(List<String> strings) throws Exception {
return Observable.fromIterable(strings);
}
}).take(5).subscribe(new Consumer<Object>() {
@Override
public void accept(Object s) throws Exception {
Log.e(TAG,"--takeOperation-->"+s);
}
});
执行结果:
RxActivity: --takeOperation-->a
RxActivity: --takeOperation-->b
throttleFirst
throttleFirst操作符会定期发射这个时间段里源Observable 发射的第一个数据,throttleFirst 操作符默认在computation 调度器上执行。
Observable.create(new io.reactivex.rxjava3.core.ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(io.reactivex.rxjava3.core.@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
for (int i=0;i<10;i++){
emitter.onNext(i);
Thread.sleep(100);
}
emitter.onComplete();
}
}).throttleFirst(200,TimeUnit.MILLISECONDS).subscribe(s->
Log.e(TAG,"-throttleFirst-->"+s)
);
执行结果:
RxActivity: -throttleFirst-->0
RxActivity: -throttleFirst-->2
RxActivity: -throttleFirst-->5
RxActivity: -throttleFirst-->7
RxActivity: -throttleFirst-->9
每隔100ms 发射一个数据,throttleFirst操作符设定的时间为200ms,因此,它会发射每个200ms 内的第一个数据。
throttleWithTimeout
通过时间来限流。源Observable每次发射出来一个数据后就会进行计时。如果在设定好的时间结束前源Observable有新的数据发射出来,这个数据就会被丢弃,同时throttleWithTimeout重新开始计时。如果每次都是在计时结束前发射数据,那么这个限流就会走极端;只会发射最后一个数据。其默认在computation 调度器上执行。
Observable.create(new io.reactivex.rxjava3.core.ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(io.reactivex.rxjava3.core.@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
for (int i=0;i<10;i++){
emitter.onNext(i);
int sleep=100;
if (i%3==0){
sleep=300;
}
Thread.sleep(sleep);
}
emitter.onComplete();
}
}).throttleWithTimeout(200,TimeUnit.MILLISECONDS).subscribe(s->
Log.e(TAG,"-throttleWithTimeOut-->"+s)
);
执行结果:
RxActivity: -throttleWithTimeOut-->0
RxActivity: -throttleWithTimeOut-->3
RxActivity: -throttleWithTimeOut-->6
RxActivity: -throttleWithTimeOut-->9
组合操作符
merge
可作用所有数据源类型,用于合并多个数据源到一个数据源
Observable<String> source1 = Observable.just("Hello", "World");
Observable<String> source2 = Observable.just("Internet", "I","Love");
source1.mergeWith(source2).subscribe(s->{
Log.e("funMerge","---->"+s);
});
Observable.merge(source1,source2).subscribe(s -> {
Log.e("funMerge","---->"+s);
});
打印数据:
funMerge: ---->Hello
funMerge: ---->World
funMerge: ---->Internet
funMerge: ---->I
funMerge: ---->Love
merge在合并数据源时,如果一个合并发生异常后会立即调用观察者的onError方法,并停止合并,通过mergeDelayError操作符,将发生的异常留到最后处理。
Observable<String> source1 = Observable.just("Hello", "World");
Observable<String> source2 = Observable.just("Internet", "I","Love");
// 合并发生异常处理
Observable<Object> error = Observable.error(new NullPointerException("error"));
Observable.mergeDelayError(source1,error,source2).subscribe(s -> {
Log.e("funMergeError","---->"+s);
},e->{
Log.e("funMergeError","---->"+e.getMessage());
});
Zip
将多个Observable发送的事件结合到一起,然后发送这些组合到一起的事件.它只发射与发射数据项最少的那个Observable一样多的数据
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Log.d("funZip", "emit 1");
emitter.onNext(1);
Thread.sleep(1000);
Log.d("funZip", "emit 2");
emitter.onNext(2);
Thread.sleep(1000);
Log.d("funZip", "emit 3");
emitter.onNext(3);
Thread.sleep(1000);
Log.d("funZip", "emit 4");
emitter.onNext(4);
Thread.sleep(1000);
Log.d("funZip", "emit complete1");
emitter.onComplete();
}
}).subscribeOn(Schedulers.io());
Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
Log.d("funZip", "emit A");
emitter.onNext("A");
Thread.sleep(1000);
Log.d("funZip", "emit B");
emitter.onNext("B");
Thread.sleep(1000);
Log.d("funZip", "emit C");
emitter.onNext("C");
Thread.sleep(1000);
Log.d("funZip", "emit complete2");
emitter.onComplete();
}
}).subscribeOn(Schedulers.io());
Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
@Override
public String apply(Integer integer, String s) throws Exception {
return integer + s;
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.d("funZip", "onSubscribe");
}
@Override
public void onNext(String value) {
Log.d("funZip", "onNext: " + value);
}
@Override
public void onError(Throwable e) {
Log.d("funZip", "onError");
}
@Override
public void onComplete() {
Log.d("funZip", "onComplete");
}
});
执行结果:
D/TAG: onSubscribe
D/TAG: emit A
D/TAG: emit 1
D/TAG: onNext: 1A
D/TAG: emit B
D/TAG: emit 2
D/TAG: onNext: 2B
D/TAG: emit C
D/TAG: emit 3
D/TAG: onNext: 3C
D/TAG: emit complete2
D/TAG: onComplete
concat
将多个Observable发射的数据进行合并发射。concat严格按照顺序发射数据,前一个Observable没发射完成是不会发射后一个Observable数据的。
Observable<Integer> source1 = Observable.just(3, 4, 5, 6)
.subscribeOn(io.reactivex.rxjava3.schedulers.Schedulers.io());
Observable<Integer> source2 = Observable.just(1, 2);
Observable.concat(source1,source2).subscribe(integer -> {
Log.e(TAG,"-concatOperation-->"+integer);
});
执行结果:
RxActivity: -concatOperation-->3
RxActivity: -concatOperation-->4
RxActivity: -concatOperation-->5
RxActivity: -concatOperation-->6
RxActivity: -concatOperation-->1
RxActivity: -concatOperation-->2
combineLastest
当两个Observable中的任何一个发射了数据时,使用了一个函数结合每个Observable发射的最近数据项,并且基于这个函数的结果发射数据。combineLastest操作符作用于最近发射的数据项,在原始Observable中的任意一个发射了数据时发射了一条数据。
Observable<Integer> source1 = Observable.just(3, 4, 5, 6);
Observable<String> source2 = Observable.just("A", "B", "c");
Observable.combineLatest(source1, source2, new BiFunction<Integer, String, String>() {
@Override
public String apply(Integer integer, String s) throws Throwable {
return integer+","+s;
}
}).subscribe(new io.reactivex.rxjava3.functions.Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
Log.e(TAG,"-combineLastest-->"+s);
}
});
执行结果:
RxActivity: -combineLastest-->6,A
RxActivity: -combineLastest-->6,B
RxActivity: -combineLastest-->6,c
如果其中的一个Observable还有数据没有发射,那么combineLastest操作符会将两个Observable最新发射的数据组合在一起。如上面的例子,第一个Observable最新的数据是6,然后第二个Observable的数据依次在变,然后再把它们组合在一起。
错误处理操作符
拦截原始Observable的onError通知,将它替换为其他数据项或数据序列,让产生的Observale 能够正常终止或根本不终止。
onErrorReturn
Observable 遇到错误时返回原有Observable 行为的备用Observable,备用Observable会忽略原有Observable的onError 调用,不会将错误传递给观察者。作为替代,它会发射一个特殊的项并调用观察者的onCompleted方法
Observable.create(new io.reactivex.rxjava3.core.ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(io.reactivex.rxjava3.core.@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onError(new Throwable("抛出异常"));
emitter.onNext(4);
emitter.onComplete();
}
}).onErrorReturn(new io.reactivex.rxjava3.functions.Function<Throwable, Integer>() {
@Override
public Integer apply(Throwable throwable) throws Throwable {
Log.e(TAG,"--->执行onErrorReturn方法");
return 0;
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG,"----onSubscribe->");
}
@Override
public void onNext(@NonNull Integer integer) {
Log.e(TAG,"----onNext->"+integer);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG,"----onError->"+e.getMessage());
}
@Override
public void onComplete() {
Log.e(TAG,"----onComplete->");
}
});
执行结果:
E/RxActivity: ----onSubscribe->
RxActivity: ----onNext->1
RxActivity: ----onNext->2
RxActivity: ----onNext->3
RxActivity: --->执行onErrorReturn方法
RxActivity: ----onNext->0
RxActivity: ----onComplete->
onErrorResumeNext
Observable 遇到错误时返回原有Observable行为的备用Observable,备用Observable会忽略原有Observable的onError 调用,不会将错误传递给观察者。作为替代,它会发射备用Observable的数据。
Observable.create(new io.reactivex.rxjava3.core.ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(io.reactivex.rxjava3.core.@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onError(new Throwable("抛出异常"));
emitter.onNext(4);
emitter.onComplete();
}
}).onErrorResumeNext(new io.reactivex.rxjava3.functions.Function<Throwable, io.reactivex.rxjava3.core.ObservableSource<? extends Integer>>() {
@Override
public io.reactivex.rxjava3.core.ObservableSource<? extends Integer> apply(Throwable throwable) throws Throwable {
Log.e(TAG,"----onErrorResumeNext->");
return Observable.just(0);
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG,"----onSubscribe->");
}
@Override
public void onNext(@NonNull Integer integer) {
Log.e(TAG,"----onNext->"+integer);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG,"----onError->"+e.getMessage());
}
@Override
public void onComplete() {
Log.e(TAG,"----onComplete->");
}
});
执行结果:
RxActivity: ----onNext->1
RxActivity: ----onNext->2
RxActivity: ----onNext->3
RxActivity: ----onErrorResumeNext->
RxActivity: ----onNext->0
RxActivity: ----onComplete->
retry
retry 操作符不会将原始Observable的onError通知传递给观察者,它会订阅这个Observable,再给它一次机会无错误地完成其数据序列。retry 总是传递onNext通知给观察者,由于重新订阅,这可能会造成数据项重复。它指定最多重新订阅的次数。如果次数超了,它不会尝试再次订阅,而会把最新的一个onError 通知传递给自己的观察者。
Observable.create(new io.reactivex.rxjava3.core.ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(io.reactivex.rxjava3.core.@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
for (int i = 0; i < 5; i++) {
if (i == 1) {
emitter.onError(new Throwable("Throwable"));
} else {
emitter.onNext(i);
}
}
emitter.onComplete();
}
}).retry(2).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG,"----retry->onSubscribe");
}
@Override
public void onNext(@NonNull Integer integer) {
Log.e(TAG,"----retry->onNext:"+integer);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG,"----retry->onError-->"+e.getMessage());
}
@Override
public void onComplete() {
Log.e(TAG,"----retry->onComplete");
}
});
执行结果:
RxActivity: ----retry->onSubscribe
RxActivity: ----retry->onNext:0
RxActivity: ----retry->onNext:0
RxActivity: ----retry->onNext:0
RxActivity: ----retry->onError-->Throwable
布尔操作符
all
all 操作符根据一个函数对源Observable发射的所有数据进行判断,最终返回的结果就是这个判断结果。这个函数使用发射的数据作为参数,内部判断所有的数据是否满足定义好的判断条件。如果全部都满足则返回true,否则就返回false。
Observable.just(1,2,3,4).all(new Predicate<Integer>() {
@Override
public boolean test(Integer integer) throws Throwable {
return integer<3;
}
}).subscribe(new SingleObserver<Boolean>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG,"----allOperation->onSubscribe");
}
@Override
public void onSuccess(@NonNull Boolean aBoolean) {
Log.e(TAG,"----allOperation->onSuccess:"+aBoolean);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG,"----allOperation->onError");
}
});
执行结果:
RxActivity: ----allOperation->onSubscribe
RxActivity: ----allOperation->onSuccess:false
contains
contains 操作用来判断源Observable所发射的数据是否包含某一个数据。如果包含该数据,会返回true;如果源Observable已经结束了却还没有发射这个数据,则返回false。
Observable.just(1,2,3).contains(1).subscribe(new io.reactivex.rxjava3.functions.Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Throwable {
Log.e(TAG,"----contains->"+aBoolean);
}
});
执行结果:
RxActivity: ----contains->true
isEmpty
isEmpty操作符用来判断源Observable是否发射过数据。如果发射过该数据,就会返回false;如果源Observable 已经
结束了却还没有发射过这个数据,则返回true。
Observable.just(1,2,3).isEmpty().subscribe(new io.reactivex.rxjava3.functions.Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Throwable {
Log.e(TAG,"----isEmpty->"+aBoolean);
}
});
执行结果:
RxActivity: ----isEmpty->false
条件操作符
ambArray
对于给定两个或多个Observable,它只发射首先发射数据或通知的那个Observable的所有数据。
Observable.ambArray(Observable.just(1,2,3).delay(2,TimeUnit.SECONDS),Observable.just(4,5,6)).subscribe(new io.reactivex.rxjava3.functions.Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG,"----ambArrayOperation->"+integer);
}
});
执行结果:
RxActivity: ----ambArrayOperation->4
RxActivity: ----ambArrayOperation->5
RxActivity: ----ambArrayOperation->6
defaultIfEmpty
发射来自原始Observable的数据。如果原始Observable没有发射数据,就发射一个默认数据。
Observable.create(new io.reactivex.rxjava3.core.ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(io.reactivex.rxjava3.core.@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
emitter.onComplete();
}
}).defaultIfEmpty(1).subscribe(new io.reactivex.rxjava3.functions.Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Throwable {
Log.e(TAG,"----defalutIfEmpty->"+integer);
}
});
执行结果:
RxActivity: ----defalutIfEmpty->1
转换操作符
toList
Observable.just("Hello","Rxjava","!").toList().subscribe(new io.reactivex.rxjava3.functions.Consumer<List<String>>() {
@Override
public void accept(List<String> list) throws Throwable {
for (String item:list){
Log.e(TAG,"---->"+item);
}
}
});
执行结果:
RxActivity: ---->Hello
RxActivity: ---->Rxjava
RxActivity: ---->!
toSortedList
它会对产生的列表排序,默认是自然排序。如果发射的数据项没有实现Comparable 接口,会抛出一个异常。
Observable.just("Hello","Rxjava","!").toSortedList().subscribe(new io.reactivex.rxjava3.functions.Consumer<List<String>>() {
@Override
public void accept(List<String> list) throws Throwable {
for (String item:list){
Log.e(TAG,"--toSortedList-->"+item);
}
}
});
执行结果:
RxActivity: --toSortedList-->!
RxActivity: --toSortedList-->Hello
RxActivity: --toSortedList-->Rxjava
toMap
toMap 操作符收集原始Observable 发射的所有数据项到一个Map(默认是HashMap),然后发射这个Map
Stu stu1=new Stu(1,"小米");
Stu stu2=new Stu(2,"小名");
Stu stu3=new Stu(3,"小李");
Observable.just(stu3,stu1,stu2).toMap(new io.reactivex.rxjava3.functions.Function<Stu, Integer>() {
@Override
public Integer apply(Stu stu) throws Throwable {
return stu.getNum();
}
}).subscribe(new io.reactivex.rxjava3.functions.Consumer<Map<Integer, Stu>>() {
@Override
public void accept(Map<Integer, Stu> StuMap) throws Throwable {
Log.e(TAG,"学号为3学生名字:"+StuMap.get(3).getName());
}
});
执行结果:
RxActivity: 学号为3学生名字:小李