【Rxjava2源码系列】基本订阅、消耗事件流程(一)

一、前言

Rx系列已经出来很久了,笔者也在很早就把他加入项目里使用了,具体使用方法相信大家都很熟悉了,这里就不多讲了。可是虽然用了很久,一旦过一段时间不接触就会生疏,用的时候也比较忐忑,生怕哪里会出问题。所以下决心研究一下他的源码,所谓知己知彼百战不殆。

这里就不列出使用方法了,网上资料已经很多了,也可以去官网上看。我觉得RX最核心的就是:异步以及他的操作符。本文先了解一下他的基本流程,他究竟是如何实现订阅的。

二、创建observable-create

最简单最直接的方式创建一个Observable的方式如下:

Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("1");
                e.onComplete();
            }
        })

传入了一个ObservableOnSubscribe对象,我们跟进去看看

    @SchedulerSupport(SchedulerSupport.NONE)
    public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        ObjectHelper.requireNonNull(source, "source is null");//null检查
        return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
    }

首先进行null检查,然后调用的RxJavaPlugins的onAssembly方法,他其实就是提供一个”钩子”,方便使用者进行hook,说的直白一点就是可以在调用的时候更改内部逻辑,比如这里的ObservableCreate,可以提前就设定其一定会更换为ObservableXXXX,可能你还不懂,但是没关系不影响阅读,你就当做这句代码不存在,因为正常流程并不会使用到,我会专门写一篇文章来解释RxJavaPlugins的用法。

这里我们就当做return new ObservableCreate(source),来看看这个ObservableCreate

public final class ObservableCreate<T> extends Observable<T> {
    final ObservableOnSubscribe<T> source;

    public ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }

    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        observer.onSubscribe(parent);

        try {
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }
//省略内部类CreateEmitter等
}

这个类也很简单,保存了我们传进来的ObservableOnSubscribe,以及subscribeActual方法,这里先卖个关子等会再来详细说这个十分重要的方法。

三、订阅observer-subscribe

通常我们在最后会订阅一个observer,重写一系列方法,就像这样

//这个observable是刚刚create得来的
observable.subscribe(new Observer<String>() {                    
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe() called with: d = [" + d + "]");
                    }

                    @Override
                    public void onNext(String value) {
                        Log.d(TAG, "onNext() called with: value = [" + value + "]");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "onError() called with: e = [" + e + "]");
                    }

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

继续跟进subscribe方法

@SchedulerSupport(SchedulerSupport.NONE)
    @Override
    public final void subscribe(Observer<? super T> observer) {
        ObjectHelper.requireNonNull(observer, "observer is null");
        try {
            //RxJavaPlugins方法暂时不管
            observer = RxJavaPlugins.onSubscribe(this, observer);
            //判空
            ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
            //调用刚刚提到的subscribeActual
            subscribeActual(observer);
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            // can't call onError because no way to know if a Disposable has been set or not
            // can't call onSubscribe because the call might have set a Subscription already
            RxJavaPlugins.onError(e);

            NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
            npe.initCause(e);
            throw npe;
        }
    }

可以看见subscribe方法很简单,相当于直接调用了subscribeActual方法而已,所以我们基本可以把他们画上等号:subscribe==subscribeActual,这下让我好好来看看这个subscribeActual方法

    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        //new了一个CreateEmitter并传入observer
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        //调用observer的onSubscribe方法
        observer.onSubscribe(parent);

        try {
            //这里的source就是刚才保存的ObservableOnSubscribe
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

这里才是真正干事的方法,需要注意几点

1、onSubscribe方法是和subscribeActual方法同线程调用,而不是和onNext及其他方法相同

2、最后调用了ObservableOnSubscribe的subscribe方法,也就是我们实现的方法,并传入了parent

3、parent其实就是CreateEmitter,利用装饰模式对observer进行了一些修改,下面是它的代码

static final class CreateEmitter<T>
    extends AtomicReference<Disposable>
    implements ObservableEmitter<T>, Disposable {


        private static final long serialVersionUID = -3434801548987643227L;

        final Observer<? super T> observer;

        CreateEmitter(Observer<? super T> observer) {
            this.observer = observer;
        }

        @Override
        public void onNext(T t) {
            if (t == null) {
                onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
                return;
            }
            if (!isDisposed()) {
                observer.onNext(t);
            }
        }

        @Override
        public void onError(Throwable t) {
            if (t == null) {
                t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
            }
            if (!isDisposed()) {
                try {
                    observer.onError(t);
                } finally {
                    dispose();
                }
            } else {
                RxJavaPlugins.onError(t);
            }
        }

        @Override
        public void onComplete() {
            if (!isDisposed()) {
                try {
                    observer.onComplete();
                } finally {
                    dispose();
                }
            }
        }

        @Override
        public void setDisposable(Disposable d) {
            DisposableHelper.set(this, d);
        }

        @Override
        public void setCancellable(Cancellable c) {
            setDisposable(new CancellableDisposable(c));
        }

        @Override
        public ObservableEmitter<T> serialize() {
            return new SerializedEmitter<T>(this);
        }

        @Override
        public void dispose() {
            DisposableHelper.dispose(this);
        }

        @Override
        public boolean isDisposed() {
            return DisposableHelper.isDisposed(get());
        }
    }

很明显,只是做了一些“是否被销毁或取消”的判断,真正调用的还是我们的observer的方法。

所以当我们在自己实现的subscribe方法里调用onNext时,就会调用到最下方订阅(subscribe)的observer的onNext方法,其他方法类似。

好了,这里已经整理清楚了初步的流程,献上一张图
这里写图片描述

四、整体流程

接下来我们就简单的看看一下Rx的用法,再整体理一遍流程

Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("1");
                e.onComplete();
            }
        })
                .map(new Function<String, String>() {
                    @Override
                    public String apply(String s) throws Exception {
                        return "_"+s;
                    }
                })
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe() called with: d = [" + d + "]");
                    }

                    @Override
                    public void onNext(String value) {
                        Log.d(TAG, "onNext() called with: value = [" + value + "]");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "onError() called with: e = [" + e + "]");
                    }

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

这是我们最常写的代码,利用map操作符把源头发射出来的数据做了一点修改,我这里为了简单就只是加了一个下划线。create和subscribe都看过了,这里我们来初步了解一下rxjava操作符干的事情。

    @SchedulerSupport(SchedulerSupport.NONE)
    public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
        ObjectHelper.requireNonNull(mapper, "mapper is null");
        return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
    }

和create如出一辙,我们来看看ObservableMap的实现

public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
    final Function<? super T, ? extends U> function;

    public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
        super(source);
        this.function = function;
    }

    @Override
    public void subscribeActual(Observer<? super U> t) {
        source.subscribe(new MapObserver<T, U>(t, function));
    }
//省略内部类MapObserver
}

和create依然相同,于是我们发现了以下内容。

1、相信很多看Rxjava源码的朋友都觉得类似ObservableOnSubscribe样式的命名很乱,我起初也根本不知道是什么意思,弄得晕头转向。不过仔细观察我们发现如下规律:

Create—ObservableCreate

map—ObservableMap

切换线程的类也一样

SubscribeOn—ObservableSubscribeOn

ObserveOn—ObservableObserveOn

其实他们都是继承了Observable而已,都是实现了subscribeActual方法,并有一个自有的Observer,来装饰onNext等方法。

2、当我们调用ObservableMap的subscribeActual方法时,相当于调用source的,而source就是map上游本身,在我们的例子当中就是ObservableCreate,而ObservableCreate的subscribeActual方法我们刚刚已经分析过了,会调用我们自己实现的subscribe方法从而触发observer的方法

于是整个流程就顺利执行下来了,无论我们中间调用多少个操作符、多少的线程调度,最终都会触发到自己实现的subscribe方法从而触发observer的方法

3、ObservableMap的subscribeActual方法中调用subscribe方法传入的MapObserver包装了真正的observer,而ObservableCreate的CreateEmitter包装的就是MapObserver,所以就是

CreateEmitter–>MapObserver–>observer

这样一层层包装过的observer传给到自己实现的subscribe方法中,当然调用CreateEmitter的onNext方法就会调用MapObserver的onNext方法,所以无论中间调用多少操作符或者线程调度,最终都会调用真正的onNext方法

于是操作符就这样生效了,当然线程调度也是这样生效的,下面就通过一张图总结一下整体流程
这里写图片描述

结束了基本流程的研究,下一篇就让我们来看看线程调度的源码实现。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值