RxJava之lift()变换原理及实现自定义 Operator
来源:互联网 发布:linux java开发 编辑:程序博客网 时间:2024/04/28 02:05
RxJava之lift()变换原理及实现自定义 Operator
map,flatMap等实质上都是针对事件序列的处理和再发送。而在 RxJava 的内部,它们是基于同一个基础的变换方法: lift(Operator)
需要了解的一些知识
Observer 是 Subscriber 的抽象父类,Subscriber只是比Observer 多了onStart(),unsubscribe()等方法。
在 RxJava 的 subscribe 过程中,Observer 也总是会先被转换成一个 Subscriber 再使用。所以如果你只想使用基本功能,选择 Observer 和 Subscriber 是完全一样的。
onStart(): 这是 Subscriber 增加的方法。它会在 subscribe 刚开始,而事件还未发送之前被调用,可以用于做一些准备工作,例如数据的清零或重置。这是一个可选方法,默认情况下它的实现为空。需要注意的是,如果对准备工作的线程有要求(例如弹出一个显示进度的对话框,这必须在主线程执行), onStart() 就不适用了,因为它总是在 subscribe 所发生的线程被调用,而不能指定线程。要在指定的线程来做准备工作,可以使用 doOnSubscribe() 方法,具体可以在后面的文中看到。
unsubscribe(): 这是 Subscriber 所实现的另一个接口 Subscription 的方法,用于取消订阅。在这个方法被调用后,Subscriber 将不再接收事件。一般在这个方法调用前,可以使用 isUnsubscribed() 先判断一下状态。 unsubscribe() 这个方法很重要,因为在 subscribe() 之后, Observable 会持有 Subscriber 的引用,这个引用如果不能及时被释放,将有内存泄露的风险。所以最好保持一个原则:要在不再使用的时候尽快在合适的地方(例如 onPause() onStop() 等方法中)调用 unsubscribe() 来解除引用关系,以避免内存泄露的发生。
调用lift方法示例
原来的Observable:
Observable<String> originObservalbe = Observable.create(originOnSubscribe);
目标Observable:
Observable<Integer> targetObservable;
operator:将String类型转化为Integer的Observable.Operator
Observable.Operator operator = new Observable.Operator<Integer, String>() { @Override public Subscriber<? super String> call(Subscriber<? super Integer> subscriber) { return new Subscriber<String>() { @Override public void onCompleted() { subscriber.onCompleted(); } @Override public void onError(Throwable e) { subscriber.onError(e); } @Override public void onNext(String s) { int value = Integer.valueOf(s); //进行转换 subscriber.onNext(value); } }; } }
通过 lift 进行转化:
Observable<Integer> targetObservable = originObservalbe.lift(operator);
即通过该operator将originObservalbe转化为Integer类型的targetObservable
来看看lift简化版源码
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) { return new Observable<R>(new OnSubscribe<R>() { @Override public void call(Subscriber<? super R> o) { try { Subscriber<? super T> st = operator.call(o); //即执行operator,转化为我们想要的Subscriber try { //onStart是 Subscriber 相比Observer增加的方法。它会在 subscribe 刚开始, //而事件还未发送之前被调用,可以用于做一些准备工作,例如数据的清零或重置。 st.onStart(); //st即我们通过operator转化后的Subscriber, //onSubscribe是调用lift()方法之前的那个Observable的OnSubscribe,即前面的targetObservable.onSubscribe onSubscribe.call(st); } catch (Throwable e) { Exceptions.throwIfFatal(e); st.onError(e); } } catch (Throwable e) { Exceptions.throwIfFatal(e); o.onError(e); } } }); }
举个实现的例子
将String类型的值转化为Integer类型的值乘以2并返回
Observable.just("123").lift(new Observable.Operator<Integer, String>() { @Override public Subscriber<? super String> call(Subscriber<? super Integer> subscriber) { return new Subscriber<String>() { @Override public void onCompleted() { Log.i("Z-MainActivity", "onCompleted: "); subscriber.onCompleted(); } @Override public void onError(Throwable e) { Log.e("Z-MainActivity", "onError: " + e.getMessage()); subscriber.onError(e); } @Override public void onNext(String s) { Log.i("Z-MainActivity", "onNext: s:" + s); int value = Integer.valueOf(s) * 2; //转化为Integer类型的值并乘以2 subscriber.onNext(value); } }; } }).subscribe(new HastesSubscriber<Integer>() { @Override public void onNext(Integer integer) { Log.i("Z-MainActivity", "onNext: END:" + integer); } });
输出结果:
Z-MainActivity: onNext: s:123Z-MainActivity: onNext: END:246
其他
RxJava 不建议开发者自定义 Operator 来直接使用 lift(),而是建议尽量使用已有的 lift() 包装方法(如 map() flatMap() 等)进行组合来实现需求,因为直接使用 lift() 非常容易发生一些难以发现的错误。
讲述 lift() 的原理只是为了更好地了解 RxJava ,从而可以更好地使用它。参考
http://gank.io/post/560e15be2dca930e00da1083
- RxJava之lift()变换原理及实现自定义 Operator
- RxAndroid与RxJava 变换的原理值lift()
- RxJava 源码分析之 —— lift 变换
- kotlin实现简单Rxjava operator原理
- 变换的原理:lift()
- 自定义RxJava Operator
- RxJava源码分析及Lift方法
- RxJava Lift
- RxJava 之四—— Lift()详解
- RxJava 之二—— Lift()详解
- 直线hough变换原理及实现
- 霍夫变换原理及opencv实现
- RxJava使用及原理
- RxJava原理及使用
- Rxjava原理探索:切换线程,变换
- HashMap实现原理及自定义
- 浅析rxjava(二)lift
- 自定义RxJava之旅
- OpenStack网络指导手册 -基本网络概念
- 关于阿里巴巴一道笔试题
- 杭电5475/2015 ACM/ICPC Asia Regional Shanghai Online An easy problem(线段树过)
- Oracle 12c安装及RHCS高可用配置
- 在代码中改变TextView的drawableLeft的图片资源
- RxJava之lift()变换原理及实现自定义 Operator
- ubuntu安装ssh和telnet服务器
- linux-mysql-insert1
- servlet读取properties文件
- recyclerview的简单使用
- Arduino和Android通过OTG 通信
- 【虫师--系列01】在做性能测试之前需要知道什么
- 面向对象的设计模式(六),状态模式
- C++11中的std::bind