RxJava 系列之变换操作符map(2)
2017-06-08 15:18
477 查看
上一篇文章中我们详细介绍了RxJava的一些常见的使用方法,只是很简单的基础使用,这边文章中我们一起来学习下RxJava更高深的使用方法。
map()操作符就是用于变换Observable对象的,map操作符返回一个Observable对象,这样就可以实现链式调用,在一个Observable对象上多次使用map操作符,最终将最简洁的数据传递给Subscriber对象。
可能这样解释大家还不是很容易理解,下面举个例子,大家就明白了。
logcat如下:
分析下上面的代码:
当我们调用
当我们调用map方法的时候,这时候返回给我们的就是
那map操作的原理是什么呢?
unsafeCreate方法代码:
从上面代码可见,map方法就一行代码,就是创建了
在
其实
上面代码的source其实就是我们
先列出其构造方法:
上面的actual其实就是我们在上面例子中subscribe方法传递的subscriber对象,mapper也就是我们map方法中参数Func1。
当订阅者收到onNext事件的时候,我们首先会调用到
通过上面的分析,应该很清楚的说明了map操作的原理。map操作符其实就是对订阅者进行包装,有点类似拦截操作的意思,其实就是装饰者设计模式。
什么是操作符?
操作符是为了解决对Observable对象的变换的问题,操作符用于在Observable和最终的Subscriber之间修改Observable发出的事件。RxJava提供了很多很有用的操作符。map()操作符就是用于变换Observable对象的,map操作符返回一个Observable对象,这样就可以实现链式调用,在一个Observable对象上多次使用map操作符,最终将最简洁的数据传递给Subscriber对象。
可能这样解释大家还不是很容易理解,下面举个例子,大家就明白了。
怎么使用?
比如我们现在有一个需求,有一个String数组,我们利用RxJava遍历的时候,我们要对数组中每个元素都转成Integer类型,这时候我们的map操作符就很有用了。String[] nums = new String[]{"1", "2", "3"}; Subscriber subscriber = new Subscriber<Integer>() { @Override public void onCompleted() { Log.e(TAG, "onCompleted"); } @Override public void onError(Throwable e) { Log.e(TAG, "onError"); } @Override public void onNext(Integer integer) { Log.e(TAG, "onNext , integer = " + integer); } }; Observable.from(nums).map(new Func1<String, Integer>() { @Override public Integer call(String s) { return Integer.parseInt(s); } }).subscribe(subscriber);
logcat如下:
06-08 14:44:40.103 6775-6775/com.example.boguang.demo E/RxAndroidActivity: onNext , integer = 1 06-08 14:44:40.103 6775-6775/com.example.boguang.demo E/RxAndroidActivity: onNext , integer = 2 06-08 14:44:40.103 6775-6775/com.example.boguang.demo E/RxAndroidActivity: onNext , integer = 3 06-08 14:44:40.103 6775-6775/com.example.boguang.demo E/RxAndroidActivity: onCompleted
分析下上面的代码:
当我们调用
Observable.from(nums)的时候,这时候返回给我们的其实是
Observable<String>类型
当我们调用map方法的时候,这时候返回给我们的就是
Observable<Integer>类型了,也就是RxJava在map操作内部偷偷的给我们变换了类型,可谓是偷龙转凤
那map操作的原理是什么呢?
源码解析
既然map操作符这么神奇,那我们就从源码的角度看看他是怎么做到的。map内部代码:public final <R> Observable<R> map(Func1<? super T, ? extends R> func) { return unsafeCreate(new OnSubscribeMap<T, R>(this, func)); }
unsafeCreate方法代码:
public static <T> Observable<T> unsafeCreate(OnSubscribe<T> f) { return new Observable<T>(RxJavaHooks.onCreate(f)); }
从上面代码可见,map方法就一行代码,就是创建了
Observable对象,关键在实例化了
OnSubscribeMap,实例化
OnSubscribeMap需要两个参数,一个是当前对象,也就是我们上面说的第一步的
Observable<String>,第二个参数就是我们传进来的func。
在
OnSubscribeMap内部做了什么事情呢?
其实
OnSubscribeMap是继承自
OnSubscribe,所以当遍历的时候就会先执行到
OnSubscribeMap的call方法,call方法代码如下:
MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer); o.add(parent); source.unsafeSubscribe(parent);
上面代码的source其实就是我们
Observable<String>,也就是from操作返回Observable,transformer也就是map传递的参数Func1,这里
MapSubscriber对Func1进行了包装,
MapSubscriber其实是一个
Subscriber,所以当调用onNext方法的时候,其实先会调用
MapSubscriber的onNext,同理,onError和onComplete,接下来看看
MapSubscriber的onNext内部实现:
先列出其构造方法:
public MapSubscriber(Subscriber<? super R> actual, Func1<? super T, ? extends R> mapper) { this.actual = actual; this.mapper = mapper; }
上面的actual其实就是我们在上面例子中subscribe方法传递的subscriber对象,mapper也就是我们map方法中参数Func1。
@Override public void onNext(T t) { R result; try { result = mapper.call(t); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); unsubscribe(); onError(OnErrorThrowable.addValueAsLastCause(ex, t)); return; } actual.onNext(result); }
当订阅者收到onNext事件的时候,我们首先会调用到
MapSubscriber中的onNext方法,也就是上面那一段代码,在这段代码内部,首先调用了,
result = mapper.call(t),然后把map方法内部处理后的结果传递到subscriber的onNext方法
actual.onNext(result),也就这样整个流程就完成了。
通过上面的分析,应该很清楚的说明了map操作的原理。map操作符其实就是对订阅者进行包装,有点类似拦截操作的意思,其实就是装饰者设计模式。
相关文章推荐
- RxJava 系列之变换操作符flatmap(2)
- RxJava系列4:RxJava操作符-变换操作符
- RxJava变换操作符:.concatMap( )与.flatMap( )的比较
- RxJava变换操作符:.concatMap( )与.flatMap( )的比较
- RxJava变换操作符:.concatMap( )与.flatMap( )的比较(即有序对无序)
- Android RxJava操作符详解系列: 变换操作符
- RxJava系列之二 变换类操作符详解1
- RxJava系列之二 变换类操作符具体解释1
- RxJava的学习之变换操作符—map
- Android RxJava操作符详解系列: 变换操作符
- Android RxJava操作符详解系列: 变换操作符
- RxJava【变换】操作符 map flatMap concatMap buffer
- RxJava实战:变换操作符map的使用姿势及技巧
- RxJava变换操作符:.concatMap( )与.flatMap( )的比较
- Rxjava(变换类)--map
- Android拾萃 - RxJava2之变换操作符及其demo
- RxJava操作符(03-变换操作)
- RX操作符之对Observable发射的数据执行变换操作一(map、flatmap)
- RxJava系列(二、详解操作符)
- RxJava入门系列二,操作符篇