接着上篇文章讲,一般情况下,上篇文章讲的就够我们用的了。一般我们工作的环境也不会出现背压问题。但是为了既然Rxjava设计了背压策略,我又在整理资料,那就还是整理一下吧。
什么是背压问题呢?接上上篇水管的举例说,就是上游水管的水流速度大于下游水管的水流速度。上游的水管流的快,下游 的水管流的慢,来不及流出去的水就堆积在水管中,水管积水多了,就爆了,就要OOM了。
//关注点1
Observable<String> observable=Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
Log.d("TAG","subscribe");
emitter.onNext("1");
emitter.onNext("2");
emitter.onNext("3");
emitter.onComplete();
}
});
如代码所示,subscribe 方法中可以多次调用emitter.onNext()方法,这个方法调用一次就发送一个事件,如果调用的很多,而观察者处理不过来,那么这些事件就会堆积在缓存中,如果一直累计不处理,内存就不够用,出现OOM了。
Rxjava用了Flowable来处理这种问题。Flowable的用法和Observable类似,这里直接上代码。
Flowable<Object> objectFlowable = Flowable.create(new FlowableOnSubscribe<Object>() {
@Override
public void subscribe(FlowableEmitter<Object> emitter) throws Exception {
emitter.onNext("数据 --->1");
emitter.onNext("数据 --->2");
emitter.onNext("数据 --->3");
emitter.onNext("数据 --->4");
emitter.onComplete();
}
}, BackpressureStrategy.DROP);//背压策略
被观察者Flowable和Observable不一样的就是Flowable.create()方法里面多了一个参数,这个参数主要是指定缓存里多的事件怎么处理,下面还会仔细将。
还有一点不同就是观察者的不同了,如代码所示:
objectFlowable.subscribe(new Subscriber<Object>() {
@Override
public void onSubscribe(Subscription subscription) {
subscription.request(2);//每次只拉去两个世间
}
@Override
public void onNext(Object value) {
Log.i("ceshi", "onNext value = " + value);
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
Log.i("ceshi", "onComplete ");
}
});
如代码所示,onSubscribe()方法的参数发生了变化,变成了subscription,subscription.request(int n);方法指定每次观察者能处理的事件的个数为n。如果被观察者发送的事件大于2,那么观察者只处理前2个事件,剩余的多的事件放在缓存中。
链式调用
Flowable.create(new FlowableOnSubscribe<Object>() {
@Override
public void subscribe(FlowableEmitter<Object> emitter) throws Exception {
emitter.onNext("数据 --->1");
emitter.onNext("数据 --->2");
emitter.onNext("数据 --->3");
emitter.onNext("数据 --->4");
emitter.onComplete();
}
}, BackpressureStrategy.DROP)//背压策略
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Object>() {
@Override
public void onSubscribe(Subscription subscription) {
subscription.request(2);
}
@Override
public void onNext(Object value) {
Log.i("ceshi", "onNext value = " + value);
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
Log.i("ceshi", "onComplete ");
}
});
调用的结果如下:
11-29 11:46:52.311 31656-31656/com.airbridge.rxjavademo I/ceshi: onNext value = 数据 --->1
11-29 11:46:52.311 31656-31656/com.airbridge.rxjavademo I/ceshi: onNext value = 数据 --->2
如上面代码所示,被观察者Flowable中,subscribe方法里emitter.onNext()调用了四次,但是因为观察者指定的能处理的事件个数是2,即subscription.request(2)。所以 观察者回调函数onNext()只执行了前两次,剩余的事件放在缓存中。
至于被观察者发送了那么多事件,都累计在缓存中怎么处理呢,这就要看 Flowable.create()的第二个参数了,也就是背压策略。
RxJava支持的背压的方式:
- BackpressureStrategy.BUFFER
- BackpressureStrategy.DROP
- BackpressureStrategy.LATEST
BUFFER 就是不丢弃请求,把收到所有请求都缓存起来,当来请求处理时再发出去。
DROP 和 LATEST 都是丢弃请求,服务端通过请求产生配额,将配额告诉客户端,客户端收到多少配额就发送多少请求。配额消耗完之后,客户端丢弃之后的请求。
DROP即配额消耗完之后直接丢弃请求。而LATEST则缓存最后(最新)的一条请求,当服务端又发来新的配额时,将缓存的最新的请求发送给服务端。
上一篇讲的是无背压的基础使用:Rxjava的使用_1
如果需要上面的源码,可以去下载 RxjavaDemo.zip
文章里面有些东西是从别处COPY过来的,都是概念性的东西,不想打字就直接拷贝了。