RxJava2.0中引入了背压概念观察者模式分为两种
被观察者 | 观察者 | 是否支持背压 | 观察者模式的类型 |
---|---|---|---|
Observable | Observer | 不支持背压 | 观察者被动的从上游接收数据 |
Flowable | Subscriber | 支持背压 | 观察者主动向上游请求数据 |
背压的概念
背压的概念简单讲就是由于在异步操作中由于上游事件发送过快下游处理不及,导致事件堆积,最后引发OOM的问题.其中Flowable /Subscriber是支持对这种情况进行处理的.
源码解析
先写一个最简单Rx订阅栗子:
引入项目依赖
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
//RxAndroid的依赖包
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
Observable/Observer栗子:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
if (!e.isDisposed()) {
e.onNext(1);
e.onNext(2);
e.onNext(3);
e.onComplete();
}
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.i(TAG,"onSubscribe");
}
@Override
public void onNext(Integer value) {
Log.i(TAG,"onNext value:"+value);
}
@Override
public void onError(Throwable e) {
Log.i(TAG,"onError");
}
@Override
public void onComplete() {
Log.i(TAG,"onComplete");
}
});
运行结果如下:
05-29 : onSubscribe
05-29: onNext value:1
05-29: onNext value:2
05-29: onNext value:3
05-29: onComplete
点进create方法:
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
我们重点看RxJavaPlugins.onAssembly(new ObservableCreate<T>(source))
内部实现如下:
public static <T> Observable<T> onAssembly(Observable<T> source) {
Function<Observable, Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
f显然是null,而且如果我们不主动采用RxJavaPlugins.setOnObservableAssembly
f对象就一直会是null的而且一般情况我们不会给这个对象赋值.所以onCreate方法的实现可以简化为:
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
return new ObservableCreate<T>(source);
}
因此返回的是一个ObservableCreate对象,而这个对象刚好是Observable的子类,其实Observable类采用的是工厂模式设计,其中的大部分方法都是返会一个Observable对象,其他的操作符只不过提供了一个包装的方法,返回了各种各样的Observable的子类,连名称基本也都是Observable+操作符的名称;
我们再来阅读subscribe的实现,按照原来的思路subscribe的方法可以精简为
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
subscribeActual(observer);
}
点进去是抽象方法,然而我们上面已经知道实际返回的是ObservableCreate对象在这个类中寻找对应的方法
具体实现如下:
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
这里面的逻辑很明显先调用observer.onSubscribe()方法于是首先打印出onSubscribe,然后调用source对象也就是create()中传入的对象的subscribe的subscribe方法于是依次发送出1,2,3三个事件,同时找到CreateEmitter对象的onNext方法,
@Override
public void onNext(T t) {
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
其实每次”发送”事件就是调用了观察者的observer方法于是打印出了:
05-29: onNext value:1
05-29: onNext value:2
05-29: onNext value:3
onComplete事件同样如此.
Flowable/Subscriber例子:
Flowable.create(new FlowableOnSubscribe<Integer>() {//Flowable里默认有一个大小为128的缓冲区
@Override
public void subscribe(FlowableEmitter<Integer> e) throws Exception {
debugLog(" subscribe ");
debugLog(" subscribe: " + 1);
e.onNext(1);
debugLog(" subscribe: " + 2);
e.onNext(2);
debugLog(" subscribe: " + 3);
e.onNext(3);
e.onComplete();
}
}, BackpressureStrategy.ERROR)
.subscribe(new Subscriber<Integer>() {//BackpressureStrategy.ERROR处理上下游流速不一致的策略,这个策略是直接抛出异常
@Override
public void onSubscribe(Subscription s) {//调用Subscription.cancel()也可以切断水管, 不同的地方在于Subscription增加了一个void request(long n)
debugLog(" onSubscribe ");
// s.request(Long.MAX_VALUE);//响应式拉取的关键一句代码,用于告知上游下游处理事件的能力,用于拉取数据,修改成2报背压异常
// s.request(2);//响应式拉取的关键一句代码,用于告知上游下游处理事件的能力,用于拉取数据,修改成报背压异常
//s.request(1);//测试Last策略
}
@Override
public void onNext(Integer i) {
debugLog(" onNext: " + i);
}
@Override
public void onError(Throwable t) {
debugLog(" onError: " + t);
}
@Override
public void onComplete() {
debugLog(" onComplete: ");
}
});
订阅关系的产生与Observable与Observer一致,不同之处在两点首先有这句:s.request(Long.MAX_VALUE);
这句话相当于告知上游下游处理事件的能力,
其次在FlowableEmitter发送事件回调subscrber的onNext()方法中会根据BackpressureStrategy中的背压策略,对事件采用不同的处理方式:
/**
* Represents the options for applying backpressure to a source sequence.
*/
public enum BackpressureStrategy {
/**
* OnNext events are written without any buffering or dropping.
* Downstream has to deal with any overflow.
* <p>Useful when one applies one of the custom-parameter onBackpressureXXX operators.
*/
MISSING,
/**
* Signals a MissingBackpressureException in case the downstream can't keep up.
*/
ERROR,
/**
* Buffers <em>all</em> onNext values until the downstream consumes it.
*/
BUFFER,
/**
* Drops the most recent onNext value if the downstream can't keep up.
*/
DROP,
/**
* Keeps only the latest onNext value, overwriting any previous value if the
* downstream can't keep up.
*/
LATEST
}
总结一下:
名称 | 具体实现 |
---|---|
MISSING, | 不采取任何策略,也就是说跟ObServable一样,但是在用onBackpressureXXX()的方法的时候非常很实用 |
ERROR | 当下游具有处理事件流的能力的时候直接抛出一个异常 |
BUFFER | 缓存事件,直到下游消费事件 |
DROP | 当下游不具有处理这些事件的能力的时候删除最近被发送的事件 |
LATEST | 当下游不具有处理这些事件的能力的时候保留最近被发送的事件,在下次下游发送接收数据的请求的时候这条缓存的数据将会被发送给下游 |