前言
Rxjava
,由于其基于事件流的链式调用、逻辑简洁 & 使用简单的特点,深受各大 Android
开发者的欢迎。
![Github截图](https://i-blog.csdnimg.cn/blog_migrate/63033ce27fa9d6497b9d120e485803d7.webp?x-image-process=image/format,png)
如果还不了解 RxJava
,请看文章:Android:这是一篇 清晰 & 易懂的Rxjava 入门教程
RxJava
如此受欢迎的原因,在于其提供了丰富 & 功能强大的操作符,几乎能完成所有的功能需求- 今天,我将为大家详细介绍
RxJava
操作符中最常用的 组合 / 合并操作符,并附带 Retrofit 结合 RxJava的实例Demo教学,希望你们会喜欢。
- 本系列文章主要基于
Rxjava 2.0
- 接下来的时间,我将持续推出
Android
中 Rxjava 2.0
的一系列文章,包括原理、操作符、应用场景、背压等等 ,有兴趣可以继续关注Carson_Ho的安卓开发笔记!!
目录
![示意图](https://i-blog.csdnimg.cn/blog_migrate/fb353da1f746efcd2b0c5bb46734bbdd.webp?x-image-process=image/format,png)
1. 作用
组合 多个被观察者(`Observable`) & 合并需要发送的事件
2. 类型
3. 应用场景 & 对应操作符 介绍
注:在使用RxJava 2
操作符前,记得在项目的Gradle
中添加依赖:
dependencies {
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.0.7'
}
3.1 组合多个被观察者
该类型的操作符的作用 = 组合多个被观察者
concat() / concatArray()
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事件作出响应");
}
});
Observable.concatArray(Observable.just(1, 2, 3),
Observable.just(4, 5, 6),
Observable.just(7, 8, 9),
Observable.just(10, 11, 12),
Observable.just(13, 14, 15))
.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
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
![concat()情况](https://i-blog.csdnimg.cn/blog_migrate/4e308b859402c665dc634825b55d4222.webp?x-image-process=image/format,png)
![concatArray()情况](https://i-blog.csdnimg.cn/blog_migrate/092cfc3d748268366307f9805676f273.webp?x-image-process=image/format,png)
merge() / mergeArray()
Observable.merge(
Observable.intervalRange(0, 3, 1, 1, TimeUnit.SECONDS),
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事件作出响应");
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
两个被观察者发送事件并行执行,输出结果 = 0,2 -> 1,3 -> 2,4
![33333.gif](https://i-blog.csdnimg.cn/blog_migrate/3192111b32ed702edee25288e0d2ebdb.webp?x-image-process=image/format,png)
concatDelayError() / mergeDelayError()
![示意图](https://i-blog.csdnimg.cn/blog_migrate/6873e7df820545866145ac72139e47ae.webp?x-image-process=image/format,png)
a. 无使用concatDelayError()的情况
Observable.concat(
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onError(new NullPointerException());
emitter.onComplete();
}
}),
Observable.just(4, 5, 6))
.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
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
测试结果:第1个被观察者发送Error事件后,第2个被观察者则不会继续发送事件
![示意图](https://i-blog.csdnimg.cn/blog_migrate/4944182a2a023d737a6bfcc06911dd39.webp?x-image-process=image/format,png)
<-- 使用了concatDelayError()的情况 -->
Observable.concatArrayDelayError(
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onError(new NullPointerException());
emitter.onComplete();
}
}),
Observable.just(4, 5, 6))
.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
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
测试结果:第1个被观察者的Error事件将在第2个被观察者发送完事件后再继续发送
![示意图](https://i-blog.csdnimg.cn/blog_migrate/84c4b869938022804cb7d06e740e73c9.webp?x-image-process=image/format,png)
mergeDelayError()
操作符同理,此处不作过多演示
3.2 合并多个事件
该类型的操作符主要是对多个被观察者中的事件进行合并处理。
Zip()
![示意图](https://i-blog.csdnimg.cn/blog_migrate/268b6536689f32d01cc0f934e1ae4680.webp?x-image-process=image/format,png)
- 特别注意:
- 事件组合方式 = 严格按照原先事件序列 进行对位合并
- 最终合并的事件数量 = 多个被观察者(
Observable
)中数量最少的数量
即如下图
<-- 创建第1个被观察者 -->
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Log.d(TAG, "被观察者1发送了事件1");
emitter.onNext(1);
Thread.sleep(1000);
Log.d(TAG, "被观察者1发送了事件2");
emitter.onNext(2);
Thread.sleep(1000);
Log.d(TAG, "被观察者1发送了事件3");
emitter.onNext(3);
Thread.sleep(1000);
emitter.onComplete();
}
}).subscribeOn(Schedulers.io());
<-- 创建第2个被观察者 -->
Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
Log.d(TAG, "被观察者2发送了事件A");
emitter.onNext("A");
Thread.sleep(1000);
Log.d(TAG, "被观察者2发送了事件B");
emitter.onNext("B");
Thread.sleep(1000);
Log.d(TAG, "被观察者2发送了事件C");
emitter.onNext("C");
Thread.sleep(1000);
Log.d(TAG, "被观察者2发送了事件D");
emitter.onNext("D");
Thread.sleep(1000);
emitter.onComplete();
}
}).subscribeOn(Schedulers.newThread());
<-- 使用zip变换操作符进行事件合并 -->
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");
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
![示意图](https://i-blog.csdnimg.cn/blog_migrate/639fba10aa09816af074b6b0fcd60613.webp?x-image-process=image/format,png)
- 特别注意:
- 尽管被观察者2的事件
D
没有事件与其合并,但还是会继续发送 - 若在被观察者1 & 被观察者2的事件序列最后发送
onComplete()
事件,则被观察者2的事件D也不会发送,测试结果如下
![示意图](https://i-blog.csdnimg.cn/blog_migrate/63e2b34bd7c4afc6eb2f1649a89da571.webp?x-image-process=image/format,png)
- 因为
Zip()
操作符较为复杂 & 难理解,此处将用1张图总结
![示意图](https://i-blog.csdnimg.cn/blog_migrate/1339a149fc8a3af356ebc6bd606ac5e2.webp?x-image-process=image/format,png)
关于Zip()
结合RxJava
与Rxtrofit
的实例讲解将在第4节中详细讲解
combineLatest()
Observable.combineLatest(
Observable.just(1L, 2L, 3L),
Observable.intervalRange(0, 3, 1, 1, TimeUnit.SECONDS),
new BiFunction<Long, Long, Long>() {
@Override
public Long apply(Long o1, Long o2) throws Exception {
Log.e(TAG, "合并的数据是: "+ o1 + " "+ o2);
return o1 + o2;
}
}).subscribe(new Consumer<Long>() {
@Override
public void accept(Long s) throws Exception {
Log.e(TAG, "合并的结果是: "+s);
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
![示意图](https://i-blog.csdnimg.cn/blog_migrate/20edffb1b3ed1219101fadefe3cc49b6.webp?x-image-process=image/format,png)
combineLatestDelayError()
作用类似于concatDelayError()
/ mergeDelayError()
,即错误处理,此处不作过多描述
reduce()
Observable.just(1,2,3,4)
.reduce(new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(@NonNull Integer s1, @NonNull Integer s2) throws Exception {
Log.e(TAG, "本次计算的数据是: "+s1 +" 乘 "+ s2);
return s1 * s2;
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer s) throws Exception {
Log.e(TAG, "最终计算的结果是: "+s);
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
![示意图](https://i-blog.csdnimg.cn/blog_migrate/d30232a1fce31a0358c273f273c740e9.webp?x-image-process=image/format,png)
collect()
Observable.just(1, 2, 3 ,4, 5, 6)
.collect(
new Callable<ArrayList<Integer>>() {
@Override
public ArrayList<Integer> call() throws Exception {
return new ArrayList<>();
}
}, new BiConsumer<ArrayList<Integer>, Integer>() {
@Override
public void accept(ArrayList<Integer> list, Integer integer)
throws Exception {
list.add(integer);
}
}).subscribe(new Consumer<ArrayList<Integer>>() {
@Override
public void accept(@NonNull ArrayList<Integer> s) throws Exception {
Log.e(TAG, "本次发送的数据是: "+s);
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
![示意图](https://i-blog.csdnimg.cn/blog_migrate/2ac41bea0d7f6b733729dbf4b931da2a.webp?x-image-process=image/format,png)
3.3 发送事件前追加发送事件
startWith() / startWithArray()
<-- 在一个被观察者发送事件前,追加发送一些数据 -->
Observable.just(4, 5, 6)
.startWith(0)
.startWithArray(1, 2, 3)
.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事件作出响应");
}
});
<-- 在一个被观察者发送事件前,追加发送被观察者 & 发送数据 -->
Observable.just(4, 5, 6)
.startWith(Observable.just(1, 2, 3))
.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
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
![示意图](https://i-blog.csdnimg.cn/blog_migrate/a7b828bb8bd4dbcbd6f59989d5758ba9.webp?x-image-process=image/format,png)
![示意图](https://i-blog.csdnimg.cn/blog_migrate/91b57e4661eb1fd5cd60b598775c2ac1.webp?x-image-process=image/format,png)
3.4 统计发送事件数量
count()
Observable.just(1, 2, 3, 4)
.count()
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
Log.e(TAG, "发送的事件数量 = "+aLong);
}
});
![示意图](https://i-blog.csdnimg.cn/blog_migrate/58e7149e3d6880b92e4927749abd5d56.webp?x-image-process=image/format,png)
至此,RxJava 2
中的组合 / 合并操作符讲解完毕。
4. 实际开发需求案例
下面,我将讲解组合 / 合并操作符的常见实际需求:
1. 从缓存(磁盘、内存)中获取缓存数据
2. 合并数据源
3. 联合判断
- 下面,我将对每个应用场景进行实例Demo演示讲解。
4.1 获取缓存数据
4.2 合并数据源 & 同时展示
4.3 联合判断
5. Demo地址
上述所有的Demo源代码都存放在:Carson_Ho的Github地址:RxJava2_组合 / 合并操作符
6. 总结
- 下面,我将用一张图总结
RxJava2
中常用的组合 / 合并操作符
![示意图](https://i-blog.csdnimg.cn/blog_migrate/2cbd06e78e17ab46df3b14fe2e83f65c.webp?x-image-process=image/format,png)