Rxjava
RxJava通过观察者模式实现了响应式编程:响应式编程(Reactive Programming),是一种面向数据流和变化的编程范式,通俗点理解就是当一个数据发生改变,所有其他关联数据都会立即作出反应。其他有着同样广泛应用的编程范式还有命令式编程,函数式编程和面向对象编程。
RxJava1.0和RxJava2.0的核心思想都是观察者模式,只不过RxJava2.0在RxJava1.0的基础对一些方法进行了优化,例如背压等。
Rxjava操作符
just:将同种数据源组合放到被观察者上面
from:将类似数组、集合的数据源放到被观察者上面
map:将一种数据源,转化成另外一种
flatmap:将一种数据源,转化成另外一种数据,并且被转化的数据是乱序排列的
concatmap:将一种数据源,转化成另外一种数据,并且被转化的数据是按照先前的数据源顺序排序的
toList:将数组的形式转化成List集合
subscribeOn:设置Observable的call方法所在的线程,也就是数据来源的线程
observeOn:设置subscribe的call方法所在的线程,也就是数据处理的线程
filter:在被观察者的数据层过滤数据
onErrorResumeNext:出错的时候,可以指定出错的时候的被观察者
retryWhen:出错的时候,重新走一遍被订阅的过程
concat:合并相同类型的被观察者到一个被观察者身上,有点类似集合、数组拼接数据。
zip:处理多种不同结果集的数据发射,一般用得多的地方是多个网络请求组合然后统一处理业务逻辑。
Rxjava 变化操作符
map flatMap concatmap
Rxjava流程
Rxjava 的流程大概是: 1. Observable.create 创建事件源,但并不生产也不发射事件。 2. 实现 observer 接口,但此时没有也无法接受到任何发射来的事件。 3. 订阅 observable.subscribe(observer), 此时会调用具体 Observable 的实现类 中的 subscribeActual 方法, 此时会才会真正触发事件源生产事件,事件源生产出来的事件通过 Emitter 的 onNext, onError,onComplete 发射给 observer 对应的方法由下游 observer 消费掉。从而完成 整个事件流的处理。 observer 中的 onSubscribe 在订阅时即被调用,并传回了 Disposable, observer 中可 以利用 Disposable 来随时中断事件流的发射。
谁是观察者谁是被观察者
操作符用于被观察者,观察者反而是抽象对象;
被观察者是耗时操作,观察者一般是回调在主线程;
一旦订阅操作,观察者就被一层层送到被观察者里面持有,被观察者处理事件过程或结束可以调用观察者的回调,结果一层层回到观察者。称为响应事件
Android主线程
解决什么问题?
1.与Retrofit联用
2.处理异步:必要性在异步任务被观察者很多且有不同的操作需要;
3.防抖,网络嵌套,doOnNext运用
Map 操作符:被观察者传进去图片路径字符串一番耗时操作转换成bitmap返回给观察者
转换怎么解决嵌套
嵌套例子:a.登录前先检查网络耗时操作,b.网络成功检查数据库内容 c.获取服务器域名或角色权限 d.开始登录,等待跳转 e.登录成功,跳转UI ; f.异常处理
背压和非背压区别
**背压(Backpressure)**当数据流通过异步的步骤执行时,这些步骤的执行速度可能不一致。也就是说上流数据发送太快,下流没有足够的能力去处理。为了避免这种情况,一般要么缓存上流的数据,要么抛弃数据。但这种处理方式,有时会带来很大的问题。
为此,RxJava带来了backpressure的概念。背压是一种流量的控制步骤,在不知道上流还有多少数据的情形下控制内存的使用,表示它们还能处理多少数据。支持背压的有Flowable类,不支持背压的有Observable,Single, Maybe and Completable类。
从Flowable源码查看,缓存池默认大少为:128
ERROR:当被观察者发送事件大于128时,观察者抛出异常并终止接收事件,但不会影响被观察者继续发送事件。
BUFFER:与Observable一样存在背压问题,但是接收性能比Observable低,因为BUFFER类型通过BufferAsyncEmitter添加了额外的逻辑处理,再发送至观察者。
DROP:每当观察者接收128事件之后,就会丢弃部分事件。
LATEST:LATEST与DROP使用效果一样,但LATEST会保证能接收最后一个事件,而DROP则不会保证。
MISSING:MISSING就是没有采取背压策略的类型,效果跟Obserable一样。
- onBackPressure相关操作符
Flowable.interval(50,TimeUnit.MILLISECONDS)
.onBackpressureDrop()//效果与Drop类型一样
.subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.newThread())
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e(TAG,"onNext : "+(aLong));
}
});
onBackpressureBuffer :与BUFFER类型一样效果。
onBackpressureDrop :与DROP类型一样效果。
onBackpressureLaster :与LASTER类型一样效果
Flowable.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> e) throws Exception {
for(int j = 0;j<=150;j++){
e.onNext(j);
Log.i(TAG," 发送数据:"+j);
try{
Thread.sleep(50);
}catch (Exception ex){
}
}
}
//指定背压策略
},BackpressureStrategy.ERROR)
.subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.newThread())
.subscribe(new Subscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE); //观察者设置接收事件的数量,如果不设置接收不到事件
}
@Override
public void onNext(Integer integer) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e(TAG,"onNext : "+(integer));
}
@Override
public void onError(Throwable t) {
Log.e(TAG,"onError : "+t.toString());
}
@Override
public void onComplete() {
Log.e(TAG,"onComplete");
}
});
线程调度器(Schedulers)
Schedulers.computation(): 适合运行在密集计算的操作,大多数异步操作符使用该调度器。
Schedulers.io():适合运行I/0和阻塞操作.
Schedulers.single():适合需要单一线程的操作
Schedulers.trampoline(): 适合需要顺序运行的操作