简介

Rxjava 是由微软架构师 Erik Meijer 领导的团队研发出来的开源库,目的是为了提供一个一致的编程接口,以便开发者对异步操作能够进行方便的处理。Rxjava 的设计是的开发者能通过 LINQ 的风格进行异步处理,所以它能将各种判断、循环、过滤、转换等的嵌套层级拉平,以流式的方式来编程,极大地简化了代码,增强了代码的阅读性。

如何使用 Rxjava

下面先举几个例子来说明一下 Rxjava 的简单使用,注意,每一个例子都是一个不同类型的使用方式,且包含了 Rxjava 不同的组成成分。

示例 01:简单示例

下面看一个 Rxjava 使用上的一个最简示例:

Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
emitter.onNext("a");
emitter.onNext("b");
emitter.onComplete();
}
});
Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG,"onSubscribe");
}
@Override
public void onNext(String s) {
Log.d(TAG,s);
}
@Override
public void onError(Throwable e) {
Log.d(TAG,"onError");
}
@Override
public void onComplete() {
Log.d(TAG,"onComplete");
}
};
observable.subscribe(observer);
// ------------------- 打印结果 -------------
onSubscribe
a
b
onComplete

我们分析上面的示例,它包含两个对象和一个动作:被观察者(Observable)、观察者(Observer)和订阅动作 subscribe()。Rxjava 是以观察者模式为基础扩展而来的,如上示例所示,当观察者和被观察者通过订阅发生关联后,被观察者就是作为信号的发射方发射消息,而观察者接受被观察者发送来的消息。观察者的onSubscribe()方法是在subscribe()的时候便执行了,onNext()方法是被观察者执行emitter.onNext("a")发射数据的时候执行,当调用emitter.onComplete()时,观察者通过 onComplete()方法响应,当调用过程中出现某些异常时,onError(Throwable e)方法响应。

onSubscribe()的方法参数为一个 Disposable 对象,持有这个对象后,我们能够在任意位置通过调用d.dispose()停止观察者对被观察者的响应。原理我们后续再说。

示例 02:异步示例

下面我们看一个异步的示例:

Observable.just(1,2,3,4)
.subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.computation())
.map(new Function() {
@Override
public String apply(Integer integer) throws Exception {
Log.d(TAG,"apply--" + Thread.currentThread().toString());
return integer.toString();
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG,"accept--" + s + "--" + Thread.currentThread().toString());
}
});
// -----------------打印结果如下 -------------------
apply--Thread[RxComputationThreadPool-1,5,main]
apply--Thread[RxComputationThreadPool-1,5,main]
apply--Thread[RxComputationThreadPool-1,5,main]
apply--Thread[RxComputationThreadPool-1,5,main]
accept--1--Thread[main,5,main]
accept--2--Thread[main,5,main]
accept--3--Thread[main,5,main]
accept--4--Thread[main,5,main]

这个示例中引入了异步的概念,我们发现,当 observeOn 被调用后便能够指定下一步的转换等操作的工作线程,每次指定都会生效。这个功能的实现便是 Rxjava 通过调度器 Schedulers 来实现的异步调用。AndroidSchedulers 是 rxandroid 提供的一个扩展,使得后续的执行会在 Android 主线程中执行。我们可以利用调度器对异步操作进行流式的编程,调度器也是 Rxjava 重要的组成成分。

示例 03:背压示例

下面是 Rxjava 背压的一个示例。背压是指如下的情况:被观察者产生信号而观察者接受信号,对于异步的调用流来说,如果被观察者产生的信号非常快,但是观察者消化的信号非常慢,那么就会造成信号的阻塞。而 rxjava 背压的设计解决了这个问题,下游可以控制上游信号的发射速度,从而解决消化不良的问题。

Flowable.create(new FlowableOnSubscribe() {
@Override
public void subscribe(FlowableEmitter emitter) throws Exception {
for (int i = 0; i < 1000; i++) {
emitter.onNext(i+ "");
}
}
}, BackpressureStrategy.BUFFER).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG,s);
}
});

BackpressureStrategy.BUFFER是背压设计的一个模式,在这个模式下如果下游的观察者消费不了数据,那么就会无限增加缓存,直到产生 OOM,当然还有其他的背压模式。Rxjava 1.x 的版本并不是所有的 Observable 都支持背压,而 Rxjava 2.x 中 Observable 不再支持背压,而是改用 Flowable 来专门支持背压。 背压,也是 rxjava 的一个重要组成部分。