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类(用黄框框出来的),这是第一层包裹,然后调用sourcesubscribe方法,把第一层包裹作为参数传入。而source并不是自定义source,而是上一层观察者,即ObservableCreate,所以我们

③进去ObservableCreate类找subscribe方法


发现它在第一层包裹的基础上,又给它封了一层包裹,也就是把第一层包裹作为参数传入了第二层包裹即发射器

  • 也就是说最终的终点(自定义观察者)经历了两次封装,第一次是封装为MapObserver,我们称之为第一层包裹,第二次是封装为CreateEmitter,我们称之为第二层包裹。

然后调用sourcesubscribe方法,此时的source就是我们的自定义source了,然后把第二层包裹作为参数传进去

④看自定义source


然后调用了发射器的onNext方法,此时我们

⑤看发射器内部的onNext方法是如何实现的(看CreateEmitter类)


发现它调用了observeronNext方法,并且把我们传入的参数也作为参数传进去,这个observer是下一层,而不是自定义观察者。它的下一层就是ObservableMap,我们

⑥进去ObservableMap看一下


首先将我们传入的值进行了一个变换,即apply方法,然后调用下游的onNext方法将变换后的值传过去。这里我们的下游就是终点,即自定义观察者。所以就到头了。


下面我们看下这里的变换。它是调用的mapperapply方法,我们看下mapper是啥

这个mapper说到底是将function传入赋值的,而这个function又是在创建ObservableMap对象的时候传入的。我们看下怎么创建的这个ObservableMap

上图可以发现是mapper(这个mapper不是上面那个mapper,但最终值都是一样的)赋值给了function。而这个mapper就是我们在使用map操作符的时候newFunction,也就是这一部分

OK,又回到上面我们进行变换的时候的mapper.apply方法,其实这个apply方法是接口里面的方法,如下图

实现就是在上上图的红圈里实现的,也就是这个变换是我们手动变换的。
ok,以上就是带map操作符的RxJava代码执行流程的全源码分析,看起来比较乱,我们画个图表示就不乱了

这就是洋葱模型,先封包裹,然后拆包裹。

三.装饰模型

其实到这还不全,RxJava还用到了装饰模型


假如用到了两个map操作符,create方法返回的是ObservableCreate对象,然后调用map方法,相当于将ObservableCreateObservableMap包起来,然后又调用一次map方法,相当于用ObservableMapObservableMap包起来。用图表示就是这样子

先装饰完了之后,再去封包裹,再去拆包裹。


这个流程可以对比买一台电脑,电脑首先要生产出来,一个零件一个零件由内向外进行包裹,也就是装饰,生产完了之后,要封包裹才能寄出去,然后你收到快递之后要拆包裹才能使用。

以上是关于RxJava的map操作符源码分析的主要内容,如果未能解决你的问题,请参考以下文章

RxJava的map操作符源码分析

RxJava之七——RxJava 2.0 图文分析create() subscribe()map()observeOn()subscribeOn()源码

RxJava系列6(从微观角度解读RxJava源码)

浅析RxJava 1.x&2.x版本区别及原理:maplift操作符源码解析

浅析RxJava 1.x&2.x版本区别及原理:maplift操作符源码解析

Rxjava 源码解析 - 线程切换源码