RxJava 原理分析(一)订阅关系的形成

最近复习RxJava的时候发现解说RxJava的原理不多,所以,来机智的骗心心来了。

依赖:

implementation "io.reactivex.rxjava2:rxjava:2.2.4"

简单使用

待会儿讲解的原理呢,是由这个使用 demo 来讲解。

        Observable.create(new ObservableOnSubscribe() {  // 创建被观察者
            @Override
            public void subscribe(ObservableEmitter emitter) throws Exception {
                emitter.onNext(1);   // 发射器,发射一个事件
                emitter.onNext(2);
            }
        }).subscribe(new Consumer() {  // 观察者
            @Override
            public void accept(Integer integer) throws Exception {  // 用于处理 onNext 事件
                Log.d(TAG, "accept: "+integer);
            }
        }, new Consumer() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        Log.d(TAG, "accept: "+throwable.getMessage());
                    }
                });

原理解析

Observable.create(ObservableOnSubscribe)

在上面的使用demo中,这是整个订阅过程的开始:创建一个被观察者。来,我们看一下我们的被观察者是什么。

Observable.class

    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    public static  Observable create(ObservableOnSubscribe source) {
        ObjectHelper.requireNonNull(source, "source is null");  // 判空
        return RxJavaPlugins.onAssembly(new ObservableCreate(source));  // 默认直接返回这个new出来的ObservableCreate
    }

这个ObjectHelper.requireNonNull怎么判空啊?

    public static  T requireNonNull(T object, String message) {
        if (object == null) {
            throw new NullPointerException(message);
        }
        return object;
    }

简直不要太简单,就是判断输入的object是不是null,不是就返回,是就抛出异常。

那这个RxJavaPlugins又是干嘛的呢?用过的都知道,没用过推荐看一下给初学者的RxJava2.0教程(十) 。其实我们没有对这个 RxJavaPlugins 做设置的话,就是返回我们传进来的这个参数。后面我们看到这个RxJavaPlugins就可以默认为直接返回参数。

书接上文,那调用 Observable.create(ObservableOnSubscribe) ,岂不是就是把自己在外部实现的 ObservableOnSubscribe 匿名内部类包装到 ObservableCreate 中去罗。

public final class ObservableCreate extends Observable {  // 注意继承关系哦
    final ObservableOnSubscribe source;  // 最原始的目标:被观察者

    public ObservableCreate(ObservableOnSubscribe source) { 
        this.source = source;  // 传进来的是外面new的匿名内部类ObservableOnSubscribe
    }
...
}

看到这里,emmm,nice,保存住了被观察者,返回了ObservableCreate 对象。注意哦,这个时候后面一个 . 操作的就是这个 ObservableCreate对象(换言之,后面点的就是ObservableCreate中的方法)。

好的,下面就是 .subscribe

.subscribe

这个方法就很有意思了,实现了订阅这个操作,或者说,是触发了onSuscribe、onNext 等操作。

先看一下 subscribe 这个方法的重载:

    public final Disposable subscribe() {}   // 注意哦,这里的都是final方法
    public final Disposable subscribe(Consumer onNext) {}
    public final Disposable subscribe(Consumer onNext, Consumer onError) {} 
    public final Disposable subscribe(Consumer onNext, Consumer onError, Action onComplete) {}
    public final Disposable subscribe(Consumer onNext, Consumer onError, Action onComplete, Consumer onSubscribe) {}
    public final void subscribe(Observer observer) {}

有点多哈,但是实现呢?很简单,大家都调用最后一个处理,没有传参的都添上默认的 Custom 就可以了。什么叫默认实现,就是实现了接口,但是默认不处理,比如默认的Action,还有就是简单处理,比如onError,但是都不是很重要,我们主要关注我们自己实现的东西嘛。

    public final Disposable subscribe(Consumer onNext, Consumer onError) {
        return subscribe(onNext, onError, Functions.EMPTY_ACTION, Functions.emptyConsumer());
    }

    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    public final Disposable subscribe(Consumer onNext, Consumer onError,
            Action onComplete, Consumer onSubscribe) {
        ObjectHelper.requireNonNull(onNext, "onNext is null");  // 挨个判空
        ObjectHelper.requireNonNull(onError, "onError is null");
        ObjectHelper.requireNonNull(onComplete, "onComplete is null");
        ObjectHelper.requireNonNull(onSubscribe, "onSubscribe is null");

        LambdaObserver ls = new LambdaObserver(onNext, onError, onComplete, onSubscribe);  // 用一个类来包裹

        subscribe(ls);  // 包裹类的订阅

        return ls;
    }

那么这个用来包裹的 LambdaObserver 又是什么鬼呢?

public final class LambdaObserver extends AtomicReference
        implements Observer, Disposable, LambdaConsumerIntrospection {

    private static final long serialVersionUID = -7251123623727029452L;
    final Consumer onNext;
    final Consumer onError;
    final Action onComplete;
    final Consumer onSubscribe;

    public LambdaObserver(Consumer onNext, Consumer onError,
            Action onComplete,
            Consumer onSubscribe) {
        super();
        this.onNext = onNext;
        this.onError = onError;
        this.onComplete = onComplete;
        this.onSubscribe = onSubscribe;
    }
...
}

就是将四个类型(onNext,onError,onComplete,onSubscribe)封装成一个一个对象,方便对整个流程的调用。

将四个对象封装在一起了过后,就是应该是订阅了把?


    @SchedulerSupport(SchedulerSupport.NONE)
    @Override
    public final void subscribe(Observer observer) {
        ObjectHelper.requireNonNull(observer, "observer is null");
        try {
            observer = RxJavaPlugins.onSubscribe(this, observer);  // 检查需要执行预操作不,默认返回 observer
            // 判空
            ObjectHelper.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null Observer. Please change the handler provided to RxJavaPlugins.setOnObservableSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");
    
            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);  // 错误的话,捕获,并交给RxJavaPlugins#onError来处理,没有交给我们自定义的onError,莫看错啦

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

真正有用的就是 subscribeActual(observer);这一句,吐血哦,还不订阅,我都快等不及了。好嘛,大神就是大神,一看,自己没实现。后面一想,就是牛逼。

    /**
     * Operator implementations (both source and intermediate) should implement this method that
     * performs the necessary business logic and handles the incoming {@link Observer}s.
     * 

There is no need to call any of the plugin hooks on the current {@code Observable} instance or * the {@code Observer}; all hooks and basic safeguards have been * applied by {@link #subscribe(Observer)} before this method gets called. * @param observer the incoming Observer, never null */ protected abstract void subscribeActual(Observer observer);

所有的操作符都会重写这个方法,我是不是暴露了什么,emm,所有运算符返回都是 Observable 的子类,就比如说 create 返回的就是 Observable 的子类 ObservableCreate,后面就是在这基础上调用了。这里我们可以看到,其实所有的 subscribe 我们都重写不了,唯一能重写且必须重写的就是这个 subscribeActual。这就意味着,这个方法是我子类实现真正订阅的入口。

前面讲解我们知道,现在在demo中调用的是 ObservableCreate 的 subscribe,那么事情就变得很简单,我们直接找到 ObservableCreate#subscribeActual(observer) 进行分析就好。在分析之前,先用图总结下前面的东西:


RxJava 原理分析(一)订阅关系的形成_第1张图片

好的嘞,那我们接下来就看一下核心的 subscribeActual 方法如何实现的?

    @Override
    protected void subscribeActual(Observer observer) {  //传进来的就是前面的 LambdaObserver
        CreateEmitter parent = new CreateEmitter(observer);  // 发射器,每一个操作符对应的类内部都会自己实现,因为处理逻辑不一样啊
        observer.onSubscribe(parent);  // 回调了自己实现的 onSubscribe 对用的Consumer

        try {
            source.subscribe(parent);   // 这个source就是初始化类的时候传进来的被观察者,这里将发送器给了它
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);  // 这里捕获的异常才交给自己写的Consumer处理
        }
    }

这里代码不多,干的事还不少,首先是new出我们的发射器,然后触发被观察者的订阅回调,然后再,执行被观察者的subscribe方法,如果捕获到异常就交给自定义的 onError 处理。

有一个概念可以先了解,无论以后把这个对象怎么包裹,传递,只有这里才调用了被观察者 Observable 的 subscribe 方法。

接下来我们来详解一下,这个回调流程。
observer.onSubscribe(parent); 这里的 observer 是什么?传进来的 包装有自定义的观察者的 LambdaObserver ,他是 Observable 的子类。接下来看一下他的调用:

    @Override
    public void onSubscribe(Disposable d) {
        if (DisposableHelper.setOnce(this, d)) {  // 设置并判断是否是第一次
            try {
                onSubscribe.accept(this);
            } catch (Throwable ex) {
                Exceptions.throwIfFatal(ex);
                d.dispose();   // 出现异常,解除订阅
                onError(ex);   // 并向下传递
            }
        }
    }

    @Override
    public void onError(Throwable t) {
        if (!isDisposed()) {   // 判断是否断开连接
            lazySet(DisposableHelper.DISPOSED);
            try {
                onError.accept(t);   //交给自定义的消费者
            } catch (Throwable e) {
                Exceptions.throwIfFatal(e);
                RxJavaPlugins.onError(new CompositeException(t, e));
            }
        } else {
            RxJavaPlugins.onError(t);
        }
    }

很简单,对不对,就是直接调用了 onNext 消费者的 accept 方法(自定义或者默认)。出现异常,如果没有断开连接,且是第一次接收到,就交给 onError (自定义或者默认)处理。

那么 source.subscribe(parent);不会也这么简单把?
source 就是传进来的 ObservableOnSubscribe,自定义的被观察者
parent 就是发射器。这一调用,我们自己写的被观察者的逻辑就巴拉巴拉的执行了

这里就是直接就回调了。吓人。。

parent.onError(ex); 怎么实现的?这就要真正说道说道这个发射器了。

发送器是什么狗东西呢?它是ObservableCreate的静态内部类:

    static final class CreateEmitter extends AtomicReference implements ObservableEmitter, Disposable {

        final Observer observer;  // 观察者,就是传进来的 LambdaObserver

        CreateEmitter(Observer 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);  // 调用自定义的Custom回调处理
            }
        }

        @Override
        public void onError(Throwable t) { 
            if (!tryOnError(t)) {  // 交给观察者
                RxJavaPlugins.onError(t);
            }
        }

        @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()) {  //没断开,不为null
                try {
                    observer.onError(t);
                } finally {
                    dispose();  //失败直接断开连接
                }
                return true;
            }
            return false;
        }

        @Override
        public void onComplete() {
            if (!isDisposed()) {
                try {
                    observer.onComplete();  // 交给观察者
                } finally {
                    dispose();
                }
            }
        }

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

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

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

    }

咦,这结构简直不要太简单,就相当于一次中转,只不过是加入了一些容错机制。到这里整个流程要用到的类就结束了,当我们在书写被观察者的时候,使用这个发射器提交东西,就是直接调用这个东西来调用消费者的对应回调。

千言不如一图


RxJava 原理分析(一)订阅关系的形成_第2张图片

不对,放错了


RxJava 原理分析(一)订阅关系的形成_第3张图片
  1. 创建真正的被观察者包裹对象(继承于 Observable),并将自己写的真正被观察者包裹起来
  2. 调用被观察者的subscribe方法,将自己创建的观察者包裹起来
  3. 作为参数,传入ObservableCreate 对方实现的 subscribeActual(Observer) 中。
  4. 在 subscribeActual 方法中生成 emitter,并且回调被观察者的onSubscribe,确定连接关系。
  5. 自己写的被观察者的 subscribe 调用,我们可以使用 emitter 提交东西,一提交就将提交的东西交给 被观察者对应的方法执行

你可能感兴趣的:(RxJava 原理分析(一)订阅关系的形成)