RxJava的map操作符源码分析
Posted 独饮敌敌畏丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RxJava的map操作符源码分析相关的知识,希望对你有一定的参考价值。
一.前言
上一篇文章我只介绍了不带map
操作符的源码流程分析,这一篇就加上map
。其实总体流程和上一篇文章分析的是差不多的,但是这一篇会着重讲一下RxJava的洋葱模型和装饰模型,当然与map
息息相关。
二.分析下带map
的总体流程
以一个map
为例
Observable.create(new ObservableOnSubscribe<Object>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Object> emitter) throws Exception {
emitter.onNext("A");
}
})
.map(new Function<Object, Boolean>() {
@Override
public Boolean apply(@NonNull Object o) throws Exception {
return false;
}
})
.subscribe(new Observer<Boolean>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull Boolean aBoolean) {
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});
还是以订阅subscribe
为触发点。
它把自定义观察者(终点)作为参数传进去了,我们
①进去subscribe
看一下
发现subscribeActual
是一个抽象方法,我们找它的实现类,也就是调用subscribe
方法的,是ObservableMap
这个类,因为map
方法返回的就是一个ObservableMap
对象。所以我们
②进去ObservableMap
类找subscribeActual
方法
它把自定义观察者作为参数传进去了,然后给他封了一层包裹,也就是MapObserver
类(用黄框框出来的),这是第一层包裹,然后调用source
的subscribe
方法,把第一层包裹作为参数传入。而source
并不是自定义source
,而是上一层观察者,即ObservableCreate
,所以我们
③进去ObservableCreate
类找subscribe
方法
发现它在第一层包裹的基础上,又给它封了一层包裹,也就是把第一层包裹作为参数传入了第二层包裹即发射器。
- 也就是说最终的终点(自定义观察者)经历了两次封装,第一次是封装为
MapObserver
,我们称之为第一层包裹,第二次是封装为CreateEmitter
,我们称之为第二层包裹。
然后调用source
的subscribe
方法,此时的source
就是我们的自定义source
了,然后把第二层包裹作为参数传进去
④看自定义source
然后调用了发射器的onNext
方法,此时我们
⑤看发射器内部的onNext
方法是如何实现的(看CreateEmitter
类)
发现它调用了observer
的onNext
方法,并且把我们传入的参数也作为参数传进去,这个observer
是下一层,而不是自定义观察者。它的下一层就是ObservableMap
,我们
⑥进去ObservableMap
看一下
首先将我们传入的值进行了一个变换,即apply方法,然后调用下游的onNext
方法将变换后的值传过去。这里我们的下游就是终点,即自定义观察者。所以就到头了。
下面我们看下这里的变换。它是调用的mapper
的apply
方法,我们看下mapper
是啥
这个mapper
说到底是将function
传入赋值的,而这个function
又是在创建ObservableMap
对象的时候传入的。我们看下怎么创建的这个ObservableMap
类
上图可以发现是mapper
(这个mapper
不是上面那个mapper
,但最终值都是一样的)赋值给了function
。而这个mapper
就是我们在使用map
操作符的时候new
的Function
,也就是这一部分
OK,又回到上面我们进行变换的时候的mapper.apply
方法,其实这个apply
方法是接口里面的方法,如下图
实现就是在上上图的红圈里实现的,也就是这个变换是我们手动变换的。
ok,以上就是带map
操作符的RxJava代码执行流程的全源码分析,看起来比较乱,我们画个图表示就不乱了
这就是洋葱模型,先封包裹,然后拆包裹。
三.装饰模型
其实到这还不全,RxJava还用到了装饰模型
假如用到了两个map
操作符,create
方法返回的是ObservableCreate
对象,然后调用map
方法,相当于将ObservableCreate
用ObservableMap
包起来,然后又调用一次map
方法,相当于用ObservableMap
将ObservableMap
包起来。用图表示就是这样子
先装饰完了之后,再去封包裹,再去拆包裹。
这个流程可以对比买一台电脑,电脑首先要生产出来,一个零件一个零件由内向外进行包裹,也就是装饰,生产完了之后,要封包裹才能寄出去,然后你收到快递之后要拆包裹才能使用。
以上是关于RxJava的map操作符源码分析的主要内容,如果未能解决你的问题,请参考以下文章
RxJava之七——RxJava 2.0 图文分析create() subscribe()map()observeOn()subscribeOn()源码
浅析RxJava 1.x&2.x版本区别及原理:maplift操作符源码解析