写给自己看的RxJava2源码分析——操作符变化原理(二)

RxJava2的操作符变化的原理其实很简单,先通过最简单的map操作符学习。

1、map操作符

Example:

 Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter emitter) throws Exception {
                emitter.onNext(5);
                emitter.onNext(4);
                emitter.onComplete();
            }
        }).map(new Function() {

          @Override
          public String apply(Integer integer) throws Exception {
              return integer+"...";
          }
      }).subscribe(new Observer() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(String s) {
              Log.d(TAG,"onNext:"+s);
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {
                Log.d(TAG,"onComplete:");
            }
        });

结果:

D/MainActivity: onNext:5…
D/MainActivity: onNext:4…
D/MainActivity: onComplete:

通过例子可以看出:当使用map操作符时,emitter发射的数据会先被它变化(具体如何变化在apply方法中进行),变化之后的结果再传给观察者。
执行流程源码分析:
通过上一篇已经知道了RxJava2整体的执行流程,调用Observable.create方法会返回一个ObservableCreate对象,它持有ObservableOnSubscribe实例source。紧接着调用map方法进行变化
Observable#map

 public final  Observable map(Function mapper) {
        ObjectHelper.requireNonNull(mapper, "mapper is null");
        return RxJavaPlugins.onAssembly(new ObservableMap(this, mapper));
    }

点进去会发现其实map方法是Observable中的方法,它又创建并返回了一个ObservableMap对象,这个对象持有了上游的ObservableCreate对象和一个用于变化的Function实例mapper。这个mapper就是map方法传进来的匿名对象。

.map(new Function() {

          @Override
          public String apply(Integer integer) throws Exception {
              return integer+"...";
          }
      })

ObservableMap对象是重点,看看它是如何创建的?

  public ObservableMap(ObservableSource source, Function function) {
        super(source);
        this.function = function;
    }

很简单,ObservableMap持有了上游的ObservableCreate对象作为它的source,以及用于变化的function对象。

紧接着调用ObservableMap的subscribe方法并把观察者传进去,观察ObservableMap的继承结构可以发现它间接继承了Observable,因此subscribe方法最终会调用到ObservableMap的subscribeActual方法。
ObservableMap#subscribeActual

 @Override
    public void subscribeActual(Observer t) {
        source.subscribe(new MapObserver(t, function));
    }

这里调用source.subscribe方法其实就是调用它持有的ObservableCreate对象的subscribe方法,然后ObservableCreate的subscribe方法会调用到ObservableCreate的subscribeActual,接着会调用到ObservableCreate持有的ObservableOnSubscribe实例subscribe方法。

 Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter emitter) throws Exception {
                emitter.onNext(5);
                emitter.onNext(4);
                emitter.onComplete();
            }
        })

可以看到经过不停的调用上游的方法,MapObserver对象最终会被传递并封装到emitter中,然后调用emitter对象的一系列onNext方法、onComplete方法其实都是调用MapObserver中对应的onNext、onComplete方法。现在再来分下MapObserver对象。
在上面创建MapObserver对象时给他传递了观察者Observer对象和用于变化的Function对象。

  MapObserver(Observer actual, Function mapper) {
            super(actual);
            this.mapper = mapper;
        }

因此变化和发射数据的一定都是通过它完成的。这里只看MapObserver的onNext方法。
MapObserver#onNext

@Override
        public void onNext(T t) {
            if (done) {
                return;
            }

            if (sourceMode != NONE) {
                downstream.onNext(null);
                return;
            }

            U v;

            try {
                v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");//1
            } catch (Throwable ex) {
                fail(ex);
                return;
            }
            downstream.onNext(v);//2
        }

主要看注释1、2处代码,在注释1处调用mapper.apply(t)对要发射的数据进行变化,变化的结果就是v,然后再注释2处调用下游的观察者对象的onNext方法将变化的结果发送出去。这样map操作符的整体变化流程就分析完了。

总结:在通过subscribe订阅观察者时会把观察者对象和用于变化的Function对象封装到MapObserver中,然后经过流转会把MapObserver对象封装到emitter发射器中,这样当调用emitter发射器发射我们的数据时内部就会调用MapObserver中对应的方法,MapObserver又持有了用于变化的Function对象和下游观察者,因此在它发射数据时内部会先调用Function对象对象对数据进行变化,再将变化后的数据传给下游观察者。

2、compose操作符

compose操作符通常是用来消除重复代码的,比如我们在进行注册时可能经过切换线程、对结果进行变换,极端情况下还有可能做多次变化,然后再登陆逻辑同样还要进行切换线程、对结果进行变换。这部分的代码大致都是重复的,通过compose操作符我们可以对重复代码进行复用。
Example:

 Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter emitter) throws Exception {
                emitter.onNext("正在通过网络获取数据...");
                emitter.onComplete();
            }
        }).subscribeOn(Schedulers.io())
              .observeOn(AndroidSchedulers.mainThread())
              .map(new Function() {

                  @Override
                  public String apply(String integer) throws Exception {
                      return "结果";
                  }
              })
              .subscribe(new Observer() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(String s) {
              Log.d(TAG,"onNext:"+s);
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {
                Log.d(TAG,"onComplete:");
            }
        });

上面这个例子可能很常见,在子线程中访问网络,获取到数据进行变化,然后在主线程显示出来。切换线程和数据变化这部分代码可能在多组类似的过程中都会遇到,因此可以通过compose操作符对这些应用一系列相同操作符的过程来复用相同的操作。
首先:创建一个ObservableTransformer实例,需要复用的操作可以放在这个对象的apply方法中。


    private ObservableTransformer observableTransformer=new ObservableTransformer(){

        @Override
        public ObservableSource apply(Observable upstream) {
            return upstream.subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .map(new Function() {
                        @Override
                        public String apply(String integer) throws Exception {
                            return "结果";
                        }
                    });
        }
    };

以后再有相同的操作时我们就不用写切换线程、变化结果这几行代码了。
然后通过compose操作符使用observableTransformer。

 Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter emitter) throws Exception {
                emitter.onNext("正在通过网络获取数据...");
                emitter.onComplete();
            }
        }).compose(observableTransformer)  //1
              .subscribe(new Observer() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(String s) {
              Log.d(TAG,"onNext:"+s);
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {
                Log.d(TAG,"onComplete:");
            }
        });

可以看到在注释1 运用了使用了compose操作符,最终的效果和开始的例子是一样的。
compose操作符原理分析:
compose操作符是对Observable进行变化的,它接收上游的Observable返回新的Observable对象。
当调用ObservableCreate的compose方法实际上就是调用Observable的compose方法

    //Observable#compose
    public final  Observable compose(ObservableTransformer composer) {
        return wrap(((ObservableTransformer) ObjectHelper.requireNonNull(composer, "composer is null")).apply(this));
    }

在这个方法中就是调用了wrap方法,而wrap方法入参部分调用了composer对象的apply方法,然后将ObservableCreate传进去。

    private ObservableTransformer observableTransformer=new ObservableTransformer(){

        @Override
        public ObservableSource apply(Observable upstream) {
            return upstream.subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .map(new Function() {

                        @Override
                        public String apply(String integer) throws Exception {
                            return "结果";
                        }
                    });
        }
    };

可以看到apply方法接收上游的Observable然后返回新的ObservableSource(Observable 实现了ObservableSource)。因此wrap方法接受的其实就是这个新的ObservableSource对象。

//Observable#wrap
  public static  Observable wrap(ObservableSource source) {
        ObjectHelper.requireNonNull(source, "source is null");
        if (source instanceof Observable) {
            return RxJavaPlugins.onAssembly((Observable)source);//1
        }
        return RxJavaPlugins.onAssembly(new ObservableFromUnsafeSource(source));
    }

在wrap方法中将source转为Observable类型的然后就直接返回了,可以看到其实compose操作符的原理也很简单。
操作符的分析暂时告一段落了,对于其他的操作符原理其实都是大同小异。

你可能感兴趣的:(Android源码相关)