RxJava 源码学习笔记 - 创建型操作符Create

271 阅读4分钟

前言:

想要看Rxjava的源码已经很久了,一直不能坚持看下去。在这个想法的基础上打算边看边写一篇文章出来,也算是我的第一篇分享文章。

图片.png

文笔不好,写的也许会比较干,理解也不一定到位,还请看官多多见谅。

我也会把我的一些疑问写入到文章里面,还望各位多多评论,不吝赐教。

创建型操作符-Create

Observable.subscribe(Observer)

创建一个Observable并订阅它,这是最基本的一个操作,代码如下:

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                e.onNext(1);
                e.onNext(2);
                e.onComplete();
            }
        }).subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Integer i) {
                Log.d("BlackC0", "onNext: " + i);
            }

            @Override
            public void onError(Throwable e) {
                Log.d("BlackC0", "onError: "+ e.toString());
            }

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

那么这里的emitter 是由谁创建的,他们订阅的时候做了些什么呢? 我们来看看具体的方法。

    @SchedulerSupport(SchedulerSupport.NONE)
    @Override
    public final void subscribe(Observer<? super T> observer) {
        ObjectHelper.requireNonNull(observer, "observer is null"); //判空
        try {
            observer = RxJavaPlugins.onSubscribe(this, observer);//全局配置拦截

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

            subscribeActual(observer);//这个是主要方法 也是Observable的抽象方法
        } 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);//全局配置拦截Throwable

            NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
            npe.initCause(e);
            throw npe;
        }
    }    
--------------------------------------------------------------------------------------------
    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        ObjectHelper.requireNonNull(source, "source is null");
        return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));//也是经过全局拦截再最终返回的
    }
--------------------------------------------------------------------------------------------
    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        observer.onSubscribe(parent);//可以看到emitter是这里创建并且实现Disposable的接口

        try {
            source.subscribe(parent);//这里的subscribe方法和外面的subscribe方法是不一样的
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }
    

这里首先创建了一个Observable,并且实例了一个匿名内部类ObservableOnSubscribe,实现了ObservableOnSubscribe.subscribe()方法。然后创建了一个Observer,并订阅了Observable,通过Observable.subscribe()方法建立订阅关系。在Observable.subscribeActual()这个实际的订阅方法里面, observer被包装成了Emitter,调用了Observable里的ObservableOnSubscribe调用了ObservableOnSubscribe.subscribe()方法,并把emitter发送出去。

OnNext()、OnError()、onComplete()

通过以上的代码,我们知道这样子就完成了一个订阅关系,那么订阅开始之后,数据是怎么通过Observable发射到 Observer的呢。我们知道数据的发送是通过emitter进行的,所以接下来我们就来看看Emitter的实例过程。

    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) {
        //在这里我们可以看到onNext()是不允许传空值的,否则会报错
            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 (!tryOnError(t)) {//emitter的onError()会被tryOnError拦截最后再丢出到Observer层
                RxJavaPlugins.onError(t);//全局配置拦截Throwable
            }
        }

        @Override
        public boolean tryOnError(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();//可以看到为啥onError()之后就会订阅终止,因为这里取消了订阅
                }
                return true;
            }
            return false;//从这里可以看出如果再订阅取消之后 仍有错误从这里抛出的话 就会到全局配置那里去 
                         //而如果全局配置没有拦截错误的话 那么这里的错误就会直接抛出到主线程 导致崩溃 
        }

        @Override
        public void onComplete() {
            if (!isDisposed()) {
                try {
                    observer.onComplete();//这里也是,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的OnNext()、OnError()、OnComplete()方法都是由Emitter直接调用的,这个emitter只是实例化的其中一个emitter,如果想要自定义一些拦截OnNext()的方法,也可以通过实现自定义的Emitter去拦截。

Disposable

订阅、数据传递经过上面的代码,都有一定的了解了。那么订阅的主动取消,是怎么一个流程呢? 我们现在有的线索就是emitter实现的两个方法:dispose()和isDisposed()。 接下来我们就一起看看这里面的方法写了啥。由于代码比较长,我就把主要的几个方法节选出来。

public enum DisposableHelper implements Disposable {
    /**
     * The singleton instance representing a terminal, disposed state, don't leak it.
     */
    DISPOSED
    ;
  
    public static boolean isDisposed(Disposable d) {
        return d == DISPOSED;
    }

    public static boolean dispose(AtomicReference<Disposable> field) {
        Disposable current = field.get();
        Disposable d = DISPOSED;
        if (current != d) {
            current = field.getAndSet(d);
            if (current != d) {
                if (current != null) {
                    current.dispose();
                }
                return true;
            }
        }
        return false;
    }

    @Override
    public void dispose() {
        // deliberately no-op
    }

    @Override
    public boolean isDisposed() {
        return true;
    }
}

我们可以看到DisposableHelper这个类本身是一个枚举类,单例了一个取消订阅的Disposable。 而确认订阅是否取消了的本质,就是用当前的Disposable去和DisposableHelper.DISPOSED做对比, 如果两者不一致,那么就没有取消,如果两者一致,就代表当前订阅取消了。 而取消订阅,就是将原先的Disposable替换成DisposableHelper.DISPOSED,由于AtomicReference 涉及到了我的知识盲区,这里就不做过多赘述。

结语

以上就是Create操作符的全部内容,希望各位多多评论,多多点赞~ 图片.png