map()原理分析_RxJava2.0操作符理解篇

我们知道map操作符是Rxjava中很常见的一个操作符,它可以实现单类型转换,那么它的这个转换内部原理是怎么实现呢,我们通过源代码一步步看一下:
先写个简单的例子,例如我想实现简单的整形转字符串:

Observer endObserver = new Observer() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.print("onSubscribe");
            }

            @Override
            public void onNext(String s) {
                System.out.print("onNext:"+s);
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        };
Observable.just(200)
                .map(new Function() {

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

为了便于理解,我们上面的写法可以拆分成这样写:

Observable observable_just = Observable.just(200);
Observable observable_map = observable_just.map(new Function(){

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

这样我们看到有两个observable,但这两个observable是不是同一个还不知道,我们通过查看map方法的源代码看一看:

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

这里看到map方法返回的是RxJavaPlugins类的onAssembly方法的返回值,而onAssembly返回的其实就是方法里传入的参数,即这里的new ObservableMap(this, mapper)。
重点:这里看到它new了一个ObservableMap,那ObservableMap又是什么呢? 其实看它继承关系就知道它继承自Observable。那么这里就能回答我们之前例子里的疑问:observable_just 和 observable_map其实不是同一个Observable,因为observable_just具体是ObservableJust,而observable_map刚才看到它是一个ObservableMap。

ObservableMap

我们看到ObservableMap的构造函数接收两个参数(this,mapper),this就是ObservableJust对象,mapper就是map方法里我们写的Function;
到这里我们知道map返回的是新创建的一个Observable,那么执行subscribe订阅操作的就是map返回的这个被观察者。那么就有问题了,这个新的被观察者去执行订阅了,我的原始被观察者observable_just怎么把数据发出去呢,什么时候发呢?下面我们通过看subscribe这个方法的代码看能不能找到里面隐藏的逻辑:

    @SchedulerSupport(SchedulerSupport.NONE)
    @Override
    public final void subscribe(Observer observer) {
        ObjectHelper.requireNonNull(observer, "observer is null");
        try {
            observer = RxJavaPlugins.onSubscribe(this, observer);

            ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");

            subscribeActual(observer); //实际执行订阅的是这个方法
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } 
    }

subscribe方法里面实际执行的是subscribeActual方法,而subscribeActual又是一个抽象方法,具体逻辑实在子类实现的,那么我们就得看ObservableMap的subscribeActual方法实现了:

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

这里看到subscribeActual方法内部是调用了source的subscribe,并且这里又new了一个MapObserver,这里我们先不管这个MapObserver是什么,后面再来分析。我们先看这个source是什么:

还记得之前map方法里new 的ObservableMap吗:

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

我们再看一下ObservableMap的代码:

public final class ObservableMap extends AbstractObservableWithUpstream {
    final Function function;

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

看到这里清楚了,原来source就是我们new ObservableMap 时传的第一个参数this,即就是ObservableJust对象;

ObservableJust

那么我们是不是就应该看ObservableJust类里的subscrib方法了

public interface ObservableSource {

    /**
     * Subscribes the given Observer to this ObservableSource instance.
     * @param observer the Observer, not null
     * @throws NullPointerException if {@code observer} is null
     */
    void subscribe(@NonNull Observer observer);
}

发现是一个接口的方法,那我们通过看ObservableJust的类结构发现,ObservableJust时继承自Ovservable,实现了ObservableSource接口, 而Ovservable的subscribe方法实际上最终调用的是抽象方法subscribeActual,那我们就要看子类ObservableJust里的subscribeActual是怎么实现的:

    private final T value;
    public ObservableJust(final T value) {
        this.value = value;
    }

    @Override
    protected void subscribeActual(Observer s) {
        ScalarDisposable sd = new ScalarDisposable(s, value);
        s.onSubscribe(sd);
        sd.run();
    }

这里终于看到s.onSubscribe(sd)调用了,说明从调用subscribe到订阅成功回调这套闭环走通了。那么

ScalarDisposable sd = new ScalarDisposable(s, value); 
sd.run();

这两段代码又是做什么呢

ScalarDisposable
public static final class ScalarDisposable
    extends AtomicInteger
    implements QueueDisposable, Runnable {

看类结构发现ScalarDisposable实现了Runnable,是一个线程类,那么它的run方法里做了什么:

        @Override
        public void run() {
            if (get() == START && compareAndSet(START, ON_NEXT)) {
                observer.onNext(value);
                if (get() == ON_NEXT) {
                    lazySet(ON_COMPLETE);
                    observer.onComplete();
                }
            }
        }

看,这里调用了observer.onNext(value),说明数据就是从这里发送给观察者的。
咦,想想,这个observer是不是我们自己写那个观察者endObserver呢?
还得回到之前的ObservableMap这里看传的是什么:

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

这里传的是new的一个MapObserver,点进去看看MapObserver是什么,发现MapObserver实现了Observer接口,就是一个观察者,而它接收了两个参数(t,function),这个t就是我们自己写的那个endObserver:

observable_map.subscribe(endObserver);

而这个function也正是我们传给map的那个Function。

MapObserver

那么既然这两个都是我们自己传的,那MapObserver是怎么执行function以及如何发生数据给我的endObserver呢,我们看MapObserver类的代码:

static final class MapObserver extends BasicFuseableObserver {
        final Function mapper;

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

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

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

            U v;

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

MapObserver父类:

    public BasicFuseableObserver(Observer actual) {
        this.actual = actual;
    }
    public final void onSubscribe(Disposable s) {
        if (DisposableHelper.validate(this.s, s)) {

            this.s = s;
            if (s instanceof QueueDisposable) {
                this.qs = (QueueDisposable)s;
            }

            if (beforeDownstream()) {

                actual.onSubscribe(this);

                afterDownstream();
            }

        }
    }

看到这是不是就明白了,原来MapObserver只是对我们自己写的观察者endObserver作了一层封装,当subscribe执行到ObservableJust类的subscribeActual方法时,调用的onSubscribe和onNext都是调用的MapObserver的onSubscribe和onNext,然后MapObserver的这两个方法里有调用了endObserver的onSubscribe和onNext,同时在onNext方法里执行了我们写的Function的apply转换,然后发送数据到endObserver的onNext中

至此,整个例子的流程算走完了,最后用一个类图总结一下整个的流程。


Observable.PNG
Observer.PNG

整个流程就是从ObservableMap的subscribe方法开始,到ObservableJust的subscribeActual,然后到MapObserver的onNext方法,这里面会执行Function的apply方法拿到转换后的数据,最后传递给endObserver的onNext方法。

你可能感兴趣的:(map()原理分析_RxJava2.0操作符理解篇)