RxJava源码阅读备忘
来源:互联网 发布:java string转map 编辑:程序博客网 时间:2024/06/03 21:37
RxJava2.0中引入了背压概念观察者模式分为两种
背压的概念
背压的概念简单讲就是由于在异步操作中由于上游事件发送过快下游处理不及,导致事件堆积,最后引发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 : onSubscribe05-29: onNext value:105-29: onNext value:205-29: onNext value:305-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}
总结一下:
- RxJava源码阅读备忘
- 备忘 - 阅读 Hibernate 源码
- webbench 源码阅读备忘
- RxJava的源码初次阅读
- 源码阅读--RxJava(一)
- 源码阅读--RxJava(三)
- 源码阅读--RxJava(二)
- RxJava学习备忘
- RxJava阅读推荐
- Android学习笔记-RxJava备忘
- RxJava&&RxAndroid学习地址备忘
- RxJava操作符学习备忘
- 《精通CSS》阅读备忘
- 《精通CSS》阅读备忘
- RxJava源码初步分析
- RxJava源码浅析
- RxJava源码分析
- RxJava源码分析
- 在Ubuntu上安装jdk
- RegExp
- bootStrap 文件引入
- Dom事件
- 自定义UITableViewCell(registerNib: 与 registerClass: 的区别)
- RxJava源码阅读备忘
- 汇编--学习笔记(九)-堆栈
- 离散题目11
- lua学习笔记2
- Python次位面——发送电子邮件
- Java 登陆失败锁定用户
- mail,postfix,postpix+mariadb,dovecot,dovecot+mariadb,postfix空壳邮件
- PHP 时间 日期
- C语言-数据结构-图的遍历