RxJava基本元素源码分析(无背压)

112 阅读12分钟
原文链接: mp.weixin.qq.com

本文是分析RxJava源码的系列文章,如果您想看到RxJava的用法相关教程,请您关注我的博客:http://shijiacheng.studio 中RxJava模块中的相关文章。

我们先看一段最简单的代码,直观的了解下整个Rxjava运行的完整流程。

// 通过creat()创建被观察者 Observable 对象Observable.create(new ObservableOnSubscribe<Integer>() {    @Override    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {        // 定义:事件发射器ObservableEmitter        // 先检查一下观察者的 isDisposed 状态        if (!emitter.isDisposed()) {            for (int i = 1; i <= 10; i++) {                // 发送数据                emitter.onNext(i);            }            // 发送结束            emitter.onComplete();        }    }    // 创建观察者 Observer 对象,并使用subscribe订阅事件}).subscribe(new Observer<Integer>() {    @Override    public void onSubscribe(Disposable d) {        System.out.println(" onSubscribe : " + d.isDisposed());    }    @Override    public void onNext(Integer integer) {        System.out.println(" onNext : " + integer);    }    @Override    public void onError(Throwable e) {        System.out.println(" onError : " + e.getMessage());    }    @Override    public void onComplete() {        System.out.println(" onComplete");    }});

主要的过程主要可以总结如下:

  1. 被观察者 Observable 如何生产事件的

  2. 被观察者 Observable 何时生产事件的

  3. 观察者Observer是何时接收到上游事件的

  4. Observable 与Observer是如何通过subscribe关联在一起的。

下面我们来一步一步分析。

. Observable

Observable是数据的上游,即事件生产者首先来分析事件是如何生成的,上面的代码中是通过 Observable.create()方法生成Observable。我们跟进去看一下:

@CheckReturnValue@NonNull@SchedulerSupport(SchedulerSupport.NONE)// ObservableOnSubscribe 是个接口,只包含subscribe方法,是事件生产的源头。public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {    // 空值判断,这里不过多关注    ObjectHelper.requireNonNull(source, "source is null");    // 生成Observable,重点关注    return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));}

上面ObservableOnSubscribe是一个接口,里面代码非常简单,只有一个subscribe,用于生产事件。

public interface ObservableOnSubscribe<T> {    /**     * Called for each Observer that subscribes.     * @param emitter the safe emitter instance, never null     * @throws Exception on error     */    void subscribe(@NonNull ObservableEmitter<T> emitter) throws Exception;}

最重要的是RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));跟进去看一下:

@SuppressWarnings({ "rawtypes", "unchecked" })@NonNullpublic static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {    Function<? super Observable, ? extends Observable> f = onObservableAssembly;    if (f != null) {        return apply(f, source);    }    return source;}

这个onAssembly是一个钩子函数(hook),通过f的值来进行判断,如果f不为空就执行apply()对传入进来的Observable进行转换,如果f为空,那么就直接返回传进来的Observable。这里的f是一个静态变量:

@SuppressWarnings("rawtypes")@Nullablestatic volatile Function<? super Observable, ? extends Observable> onObservableAssembly;

Observable.create()中并没有任何函数对onObservableAssembly赋值,所以上面的变量f为null。所以 RxJavaPlugins.onAssembly();会直接返回参数中传入的内容。所以这句话等效于:

return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));// 上面的代码等效于下面return new ObservableCreate<T>(source);

所以在这里会得到如下结论:

  • 事件的源就是new ObservableCreate()对象,将 ObservableOnSubscribe作为参数传递给ObservableCreate的构造函数。

  • 事件是由接口ObservableOnSubscribe的subscribe方法上产的,至于何时生产事件,稍后再分析。

. Observer

Observer 是数据的下游,即事件消费者。Observer是个接口。

// 接口内含4个方法,分别用于 响应 对应于被观察者发送的不同事件public interface Observer<T> {       /**         * 为观察者提供取消的方法        * 内部参数:Disposable 对象,可结束事件        *    void onSubscribe(@NonNull Disposable d);    /**     * 接收要观察的事件     */    void onNext(@NonNull T t);    /**     * 通知观察者遇到错误的情况     */    void onError(@NonNull Throwable e);    /**     * 通知观察者已完成发送     */    void onComplete();}

上游发送的事件就是在这几个方法中被消费的。

. subscribe

重点来了,接下来最重要的方法来了:observable.subscribe(observer); subscribe是将观察者(observer)与被观察者(observable)连接起来的方法。只有subscribe方法执行后,上游产生的事件才能被下游接收并处理。

@SchedulerSupport(SchedulerSupport.NONE)@Overridepublic final void subscribe(Observer<? super T> observer) {    // 空值判断    ObjectHelper.requireNonNull(observer, "observer is null");    try {        // hook方法,获取观察者observer        observer = RxJavaPlugins.onSubscribe(this, observer);        // 连接observer和observable的具体实现        subscribeActual(observer);    } catch (NullPointerException e) {    } catch (Throwable e) {    }}

这里的关键代码只有两行。

RxJavaPlugins.onSubscribe(this, observer)这个方法和上面获取被观察者Observable的方法相似。

@NonNullpublic static <T> Observer<? super T> onSubscribe(@NonNull Observable<T> source, @NonNull Observer<? super T> observer) {    BiFunction<? super Observable, ? super Observer, ? extends Observer> f = onObservableSubscribe;    if (f != null) {        return apply(f, source, observer);    }    return observer;}

这里的onObservableSubscribe同样返回null,所以这里就是直接将传入进来的observer直接返回。所以最重要的代码在subscribeActual()这个函数中。我们跟进去看一下:

protected abstract void subscribeActual(Observer<? super T> observer);

这个是Observable.java中的抽象函数。我们要看看他的具体实现,在这里实现是在上文Observable中提到的ObservableCreate类中了。

@Overrideprotected void subscribeActual(Observer<? super T> observer) {    // 初始化事件发射器    CreateEmitter<T> parent = new CreateEmitter<T>(observer);    //直接回调了观察者的onSubscribe    observer.onSubscribe(parent);    try {        // source是事件源,生产事件的接口,由我们自己实现        // 调用了事件源subscribe方法生产事件,同时将发射器传给事件源。         source.subscribe(parent);    } catch (Throwable ex) {        Exceptions.throwIfFatal(ex);        parent.onError(ex);    }}

现在我们明白了,数据源生产事件的subscribe方法只有在observable.subscribe(observer)被执行后才执行的。 换言之,事件流是在订阅后才产生的。而observable被创建出来时并不生产事件,同时也不发射事件。

. Emitter

接下来我们再来看看事件是如何被发射出去,同时observer是如何接收到发射的事件的?

CreateEmitter<T> parent = new CreateEmitter<T>(observer);static final class CreateEmitter<T>    extends AtomicReference<Disposable>    implements ObservableEmitter<T>, Disposable {    }

通过上面的代码我们可以看到CreateEmitter 实现了ObservableEmitter接口,同时ObservableEmitter接口又继承了Emitter接口。 CreateEmitter 还实现了Disposable接口,这个disposable接口是用来判断是否中断事件发射的。 从名称上就能看出,这个是发射器,故名思议是用来发射事件的,正是它将上游产生的事件发射到下游的。 Emitter是事件源与下游的桥梁。 CreateEmitter 主要包括方法:

static final class CreateEmitter<T>            extends AtomicReference<Disposable>            implements ObservableEmitter<T>, Disposable {        @Override        public void onNext(T t) {            // 判断事件是否需要被丢弃            if (!isDisposed()) {                // 调用Emitter的onNext,它会直接调用observer的onNext                observer.onNext(t);            }        }        @Override        public void onError(Throwable t) {            if (!tryOnError(t)) {                RxJavaPlugins.onError(t);            }        }        @Override        public boolean tryOnError(Throwable t) {            if (!isDisposed()) {                try {                    // 调用Emitter的onError,它会直接调用observer的onError                    observer.onError(t);                } finally {                    // 当onError被触发时,执行dispose(),                    // 后续onNext,onError, onComplete就不会继续发射事件了                    dispose();                }                return true;            }            return false;        }        @Override        public void onComplete() {            if (!isDisposed()) {                try {                    // 调用Emitter的onComplete,它会直接调用observer的onComplete                    observer.onComplete();                } finally {                    // 当onComplete被触发时,也会执行dispose(),                    // 后续onNext,onError, onComplete同样不会继续发射事件了                    dispose();                }            }        }        /**         * 释放资源、停止发送事件         */        @Override        public void dispose() {            DisposableHelper.dispose(this);        }        /**         * 判断是否已经释放了资源         */        @Override        public boolean isDisposed() {            return DisposableHelper.isDisposed(get());        }    }

CreateEmitter 的onError和onComplete方法任何一个执行完都会执行dispose()中断事件发射,所以observer中的onError和onComplete也只能有一个被执行。 现在终于明白了,事件是如何被发射给下游的。 当订阅成功后,数据源ObservableOnSubscribe开始生产事件,调用Emitter的onNext,onComplete向下游发射事件,Emitter包含了observer的引用,又调用了observer onNext,onComplete,这样下游observer就接收到了上游发射的数据。

. 总结

Rxjava的流程大概是:

  1. Observable.create 创建事件源,但并不生产也不发射事件。

  2. 实现observer接口,但此时没有也无法接受到任何发射来的事件。

  3. 订阅 observable.subscribe(observer), 此时会调用具体Observable的实现类中的subscribeActual方法, 此时会才会真正触发事件源生产事件,事件源生产出来的事件通过Emitter的onNext,onError,onComplete发射给observer对应的方法由下游observer消费掉。从而完成整个事件流的处理。

更多内容请您关注我的公众号:Android八小时之外,让我们在八小时工作之外共同进步!