##.简介
RxJava是是一个基于事件流处理来实现异步操作的库。对于需要切换线程来异步处理的场景,能够简化代码编写,提高代码可读性。官网地址: ReactiveX
一、使用流程概括和示例
1.它是按照观察者模式来设计的
被观察者负责生产事件,观察者负责处理事件,一旦观察者 订阅了 被观察者,就会触发被观察者发送事件流。这里的“事件”是一个抽象概念,它的载体是一个数据结构(例如String/Object/自定义对象等),传递的实际上是数据,只是在观察者模式中它们的角色是“事件”。事件流对应的,是要传递的数据流。

2.使用流程和示例
大致可分为3步:1)创建被观察者,编写事件生产和发送逻辑;通过事件发射器 FlowableEmitter的onNext()/onComplete()/onError()等来传递事件。2)创建观察者,编写事件处理逻辑;通过自己的 onNext()/onComplete()/onError()等来接受事件并处理。注意:上游事件发送正常结束时 onComplete()被调用, onError()在出错时被调用,二者出现时都意味着事件流处理结束,但二者只会有一个被调用到。3)观察者 订阅 被观察者,触发 被观察者生产和发送时间,然后观察者接收事件并处理。
代码示例和注释讲解:
/**
* 1.创建被观察者
* 有多种创建方式,这是其中较常见一种,通过Create()方法创建
* 第二个参数是背压策略
*/
Flowable<String> flowable = Flowable.create(new FlowableOnSubscribe<String>() {
/**
* 被订阅后,会触发调用该方法
* @param emitter 事件发射器,可通过它将事件传递给观察者
* @throws Throwable
*/
@Override
public void subscribe(@NonNull FlowableEmitter<String> emitter) throws Throwable {
//通过onNext()方法来传递事件(数据)
emitter.onNext("aaa");
emitter.onNext("bbb");
emitter.onNext("ccc”);
//调用onComplete(),意味着事件流发送已结束
//后面再调用onNext()也不会再将事件发送出去
emitter.onComplete();
}
}, BackpressureStrategy.ERROR);
/**
* 2.创建观察者
*/
FlowableSubscriber<String> flowableSubscriber = new FlowableSubscriber<String>() {
/**
* 一旦订阅,会首先调用该方法
* 传入的参数s是Subscription类型,对应的是"订阅"这个抽象概念
* 通过调用Subscription.cancel()可以取消订阅,停止事件流发送和接收
* @param s
*/
@Override
public void onSubscribe(@NonNull Subscription s) {
}
/**
* 通过该方法将数据传递过来
* @param s
*/
@Override
public void onNext(String s) {
//.....处理数据.....
}
/**
* 当出错时,该方法会被调用,事件流传递会结束掉。
* onError()和onComplete()只会有一个被调用到。
* @param t
*/
@Override
public void onError(Throwable t) {
}
/**
* 该方法被调用,意味着事件流传递已结束
* onError()和onComplete()只会有一个被调用到。
*/
@Override
public void onComplete() {
}
};
/**
* 3.订阅
* 订阅后,首先会触发观察者执行onSubscribe()方法
* 然后会触发被观察者执行FlowableOnSubscribe.subscribe()内的逻辑,
* 观察者可在此方法中写生产事件和发射的逻辑,最终事件会在观察者的回调方法中被处理
*/
flowable.subscribe(flowableSubscriber);
习惯上会把以上步骤串在一起链式调用,这样写起来、读起来都更简便:
/**
* 习惯上会把以上步骤串在一起写,这些写起来、读起来都更简便
*/
Flowable.create(new FlowableOnSubscribe<String>() {
//被订阅后,会触发调用该方法
@Override
public void subscribe(@NonNull FlowableEmitter<String> emitter) throws Throwable {
//通过onNext()方法来传递事件(数据)
emitter.onNext("aaa");
emitter.onNext("bbb");
emitter.onNext("ccc");
//调用onComplete(),意味着事件流发送已结束
//后面再调用onNext()也不会再将事件发送出去
emitter.onComplete();
}
}, BackpressureStrategy.ERROR)
//设置被观察者生产和发送事件在IO线程执行
.subscribeOn(Schedulers.io())
//设置观察者处理事件在主线程执行
.observeOn(AndroidSchedulers.mainThread())
//订阅
.subscribe(new FlowableSubscriber<String>() {
@Override
public void onSubscribe(@NonNull Subscription s) {
//一旦订阅,会首先调用该方法
}
@Override
public void onNext(String s) {
//.....处理数据.....
}
@Override
public void onError(Throwable t) {
}
@Override
public void onComplete() {
}
});
二.异步处理相关
RxJava中既可以配置被观察者生产/发送事件执行的线程,也可以配置观察者处理事件的线程,因此可以支持实现异步操作。
1.同步处理
当不做任何线程调度配置时,默认二者都会在当前线程中执行,此时被观察者、观察者是同步执行的,发送一个事件、处理一个事件,然后继续进行下一轮发送和处理。
2.异步处理
当配置二者不在同一线程执行时,事件的发送和处理是异步的,被观察者将事件发送到对应的“事件缓冲区”,然后观察者从事件缓冲区取事件来处理。
3.背压策略
异步处理时,有可能观察者处理事件较慢,而被观察者发送事件较快,则事件不停在 “事件缓冲区”堆积。 “事件缓冲区” 默认最多缓冲128个事件,一旦超出就会报错。所以需要一种策略来处理这种情况,缓解上游过快的事件流带来的压力,所以叫“背压策略”。( 背压策略是针对缓冲区的策略,除了采用背压策略外,针对该问题,也可以通过其它方案解决:控制上游发送事件速度、或者让下游放弃处理部分事件。)
背压策略有:
3.1 BackpressureStrategy.ERROR:默认使用的背压策略,缓存量超出128个就触发onError(),传递异常 MissingBackpressureException 。3.2 BackpressureStrategy.MISSING:跟 BackpressureStrategy.ERROR类似,onError()传递的信息中多了句提示内容。
3.3 BackpressureStrategy.BUFFER:将缓冲区设置为无限大,此时倒是不会报错了,但是事件如果一直在缓冲区累积下去,容易出现OOM问题。3.4 BackpressureStrategy.DROP:缓存超过128个事件时,新发送的事件会被丢弃掉。3.5 BackpressureStrategy.LATEST缓存超过128个事件时,会额外保存一个事件,只会额外保存最新发送的这个事件。
4.被观察者、观察者执行线程的配置
4.1配置方法
通过subscribeOn()方法指定被观察者生产事件的线程,可指定多次,则只有第一次指定有效。通过 observeO()指定观察者处理事件的线程,可指定多次,每次指定均有效,每指定一次,就会切换一次线程。(RxJava是通过内部的 Schedulers调度器来实现线程切换的。)
示例:
//设置被观察者生产和发送事件在IO线程执行
flowable.subscribeOn(Schedulers.io())
//设置观察者处理事件在Android主线程执行
.observeOn(AndroidSchedulers.mainThread());
4.2 RxJava内置线程类型
RxJava中内置了多种用于调度的线程类型。 RxJava使用线程池来维护这些线程,所以又较高调度效率。
类型
|
含义
|
应用场景
|
Schedulers.immediate()
|
当前线程 = 不指定线程
|
默认
|
AndroidSchedulers.mainThread()
|
Android主线程
|
操作UI
|
Schedulers.newThread()
|
常规新线程
|
耗时等操作
|
Schedulers.io()
|
io操作线程
|
网络请求、读写文件等io密集型操作
|
CPU计算操作线程
|
大量计算操作
|
三、被观察者类型
类型
|
描述
|
Observable<T>
|
能够发射0或n个数据,并以成功或错误事件终止。
|
Flowable<T>
|
能够发射0或n个数据,并以成功或错误事件终止。 支持Backpressure背压策略(事件缓冲区应对事件堆积过多时的策略)。
|
Single<T>
|
只发射单个数据或错误事件。
|
Completable
|
它从来不发射数据,只处理 onComplete 和 onError 事件。可以看成是Rx的Runnable。
|
Maybe<T>
|
能够发射0或者1个数据,要么成功,要么失败。有点类似于Optional
|
四、各种操作符
1.创建操作符:用于创建被观察者和事件

2.变换操作符:对于事件用指定函数处理后,将结果作为事件继续发送到下游
类型
|
作用
|
map()
|
1个源事件变换出一个结果事件,后继发送顺序不变
|
FlatMap()
|
源事件与结果事件对应关系随意,后继发送顺序随机
|
ConcatMap()
|
源事件与结果事件对应关系随意,后继发送顺序按照与源事件关系来排列
|
Buffer()
|
设置一个数量和步长,每轮从被观察者发送的事件集合中取指定数量发送到下游,下一轮按照步长移动后,依旧发送指定数量,不断重复此步骤知道全部发送完。
|
示例:
/**
* map示例
*/
flowable.map(new Function<String, Character>() {
@Override
public Character apply(String s) throws Throwable {
//此处将事件类型String处理成Character,发送到下游
return s.charAt(0);
}
});
3.条件判断、过滤操作符:用于根据判断条件筛选出/过滤掉部分事件


4.组合 / 合并操作符:用于合并多个被观察者事件序列
5.其它操作符
类型
|
作用
|
delay()
|
延迟指定时间发送事件
|
doOnEach()
doOnNext()
doAfterNext()
doOnError()
|
每当对应类型时间发生前/后,都会执行执行方法
|
retry()
retryWhen()
|
出错时重试
|
repeat()
repeatWhen()
|
不断重复发送
|
(声明:部分图片来自网络,侵删!)