响应式编程概述
什么是响应式编程?
是一种基于异步数据流概述的编程模式
响应式编程--关键概念
事件
响应式编程--使用场景
UI(通用)
RxJava是什么?
1.异步数据处理库
2.扩展的观察者模式
RxAndroid概述
RxAndroid是什么
1.是RxJava针对Android平台的一个扩展,用于Android开发
2.提供响应式的扩展组件快速,易于开发Android应用程序
Schedulers(调度器)
1.解决Android主线程问题
2.解决多线程问题
RxJava与观察者模式
观察者模式四大要素
1.Observable 被观察者
2.Observer 观察者
3.subscribe 订阅
4.事件
RxJava扩展的观察者模式
Create
create 操作符应该是最常见的操作符了,主要用于产生一个 Obserable 被观察者对象,为了方便大家的认知,以后的教程中统一把被观察者 Observable 称为发射器(上游事件),观察者 Observer 称为接收器(下游事件)。
Map
Map 基本算是 RxJava 中一个最简单的操作符了,它的作用是对发射时间发送的每一个事件应用一个函数,是的每一个事件都按照指定的函数去变化。
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
Log.e("onNext","onNext1");
e.onNext(1);
Log.e("onNext","onNext2");
e.onNext(2);
Log.e("onNext","onNext3");
e.onNext(3);
}
}).map(new Function() {
@Override
public String apply(Integer integer) throws Exception {
return integer+"";
}
}).subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
Log.e("integer","Integer-"+s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
输出:
map 基本作用就是将一个 Observable 通过某种函数关系,转换为另一种 Observable,上面例子中就是把我们的 Integer 数据变成了 String 类型。
zip
zip 专用于合并事件,该合并不是连接(连接操作符后面会说),而是两两配对,也就意味着,最终配对出的 Observable 发射事件数目只和少的那个相同。
Observable.zip(Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
}
}), Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(4);
e.onNext(5);
e.onNext(6);
e.onNext(7);
}
}), new BiFunction() {
@Override
public Integer apply(Integer integer, Integer integer2) throws Exception {
return integer + integer2;
}
}).subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.e("integer", integer + "");
}
});
根据log可以看出,第一个Observable发射了3个事件,第二个Observable发射了4个事件,但是最后输出的结果只有3个事件,说明zip 组合事件的过程就是分别从发射器 A 和发射器 B 各取出一个事件来组合,并且一个事件只能被使用一次,组合的顺序是严格按照事件发送的顺序来进行的,合并后的事件的数量等于少的Observable。
Concat
对于单一的把两个发射器连接成一个发射器,虽然 zip 不能完成,但我们还是可以自力更生,官方提供的 concat 让我们的问题得到了完美解决。
Observable.concat(get1(), get2())
.subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.e("integer", integer + "");
}
});
private Observable get1() {
Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
e.onComplete();
}
});
return observable;
}
private Observable get2() {
Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(4);
e.onNext(5);
e.onNext(6);
}
});
return observable;
}
可以看出两个发射器连接成了一个发射器,而且顺序不乱。注意的是,第一个发射器需要调用e.onComplete()方法,否则第二个发射器不会发射事件。
FlatMap
它可以把一个发射器 Observable 通过某种方法转换为多个 Observables,然后再把这些分散的 Observables装进一个单一的发射器 Observable。但有个需要注意的是,flatMap 并不能保证事件的顺序
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
}
}).flatMap(new Function>() {
@Override
public ObservableSource apply(Integer integer) throws Exception {
final List list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add("=value= " + integer);
}
return Observable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS);
}
}).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.e("s",s);
}
});
可以看到结果,将发射器的每个事件都做了处理并在最后统一发射,而且最后输出的结果并不是有序的。
Map和FlatMap
1.map返回的是结果集,flatmap返回的是包含结果集的Observable(返回结果不同)
2.map被订阅时每传递一个事件执行一次onNext方法,flatmap多用于多对多,一对多,再被转化为多个时,一般利用from/just进行一一分发,被订阅时将所有数据传递完毕汇总到一个Observable然后一一执行onNext方法(执行顺序不同)>>>>(如单纯用于一对一转换则和map相同)
3.map只能单一转换,单一只的是只能一对一进行转换,指一个对象可以转化为另一个对象但是不能转换成对象数组(map返回结果集不能直接使用from/just再次进行事件分发,一旦转换成对象数组的话,再处理集合/数组的结果时需要利用for一一遍历取出,而使用RxJava就是为了剔除这样的嵌套结构,使得整体的逻辑性更强。)
flatmap既可以单一转换也可以一对多/多对多转换,flatmap要求返回Observable,因此可以再内部进行from/just的再次事件分发,一一取出单一对象(转换对象的能力不同)
concatMap
上面其实就说了,concatMap 与 FlatMap 的唯一区别就是 concatMap 保证了顺序,所以,我们就直接把 flatMap 替换为 concatMap 验证吧。
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
}
}).concatMap(new Function>() {
@Override
public ObservableSource apply(Integer integer) throws Exception {
final List list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add("=value= " + integer);
}
return Observable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS);
}
}).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.e("s",s);
}
});
结果跟之前设想的一样。