Rxjava 源码系列 - 基础框架分析

212 阅读15分钟
原文链接: mp.weixin.qq.com

前言

Rxjava

RxAndroid

本篇博客讲解的 Rxjava 的原理基于版本 2.1.4,RxAndroid 的原理的版本基于 2.0.2 。

基本框架

Rxjava 有四个基本的概念

  • Observable (可观察者,即被观察者)

  • Observer (观察者)

  • subscribe (订阅) 通过该方法,将 Observable 与 Observer 关联起来

  • 事件 (包括 onNext,onComplete,onError 等事件)

简单来说:Observable 和 Observer 通过 subscribe() 方法实现订阅关系,从而 Observable 可以在需要的时候发出事件来通知 Observer,并且回调 Observer 的相应的方法。

用一张简单的图来描述大概如下

该图片来源于 给 Android 开发者的 RxJava 详解

Observable

1public abstract class Observable<T> implements ObservableSource<T> {2}

可以看到 Observable 是一个抽象类,实现了 ObservableSource 接口

Observer

Observer 其实也是一个接口,里面定义了若干方法,onSubscribe ,onNext,onError,onComplete 方法。

 1public interface Observer<T> { 2 3 4    void onSubscribe(@NonNull Disposable d); 5 6 7    void onNext(@NonNull T t); 8 910    void onError(@NonNull Throwable e);111213    void onComplete();1415}
  • 一个正常的事件序列的调用顺序会是这样的 onSubscribe > onNext > onComplete,若中途出错了,那调用顺序可能是这样的 onSubscribe > onNext > onError

  • onSubscribe 方法,当我们调用 Observable 的 subscribe 方法的时候,会先回调 Observer 的 onSubscribe 方法,此方法的调用顺序先于 onNext,onError ,onComplete 方法。

  • onError 方法与 onComplete 方法可以说是互斥的,调用了其中一个方法就不会调用另外一个方法

源码解析

基本使用

在讲解原理之前,我们先来看一下 Rxjava 的一个基本使用。

 1Observable 2           .create(new ObservableOnSubscribe<String>() { 3                @Override 4                public void subscribe(ObservableEmitter<String> emitter) throws Exception { 5                    emitter.onNext("a"); 6                    emitter.onNext("b"); 7                    emitter.onNext("c"); 8                    emitter.onComplete(); 9                }10            })11            .subscribe(new Observer<String>() {12                @Override13                public void onSubscribe(Disposable d) {14                    Log.e("TAG", "onSubscribe():  ");15                }1617                @Override18                public void onNext(String s) {19                    Log.e("TAG", "onNext():  " + s);20                }2122                @Override23                public void onError(Throwable e) {2425                }2627                @Override28                public void onComplete() {29                    Log.e("TAG", "onComplete():  ");30                }31            });
1E/TAG: onSubscribe():  2E/TAG: onNext():  a3E/TAG: onNext():  b4E/TAG: onNext():  c5E/TAG: onComplete():

首先我们先从上面简单的例子回顾起:

先来看 Observable 的 create 方法

1public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {2    ObjectHelper.requireNonNull(source, "source is null");3    return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));4}

在 create 方法中,其实很简单,只是对 source 进行判空处理,并将 source 用 ObservableCreate 包装起来,并返回回去。下面让我们一起来看一下 ObservableCreate 是什么东西?

 1public final class ObservableCreate<T> extends Observable<T> { 2    final ObservableOnSubscribe<T> source; 3 4    public ObservableCreate(ObservableOnSubscribe<T> source) { 5        this.source = source; 6    } 7 8    @Override 9    protected void subscribeActual(Observer<? super T> observer) {10        CreateEmitter<T> parent = new CreateEmitter<T>(observer);11        observer.onSubscribe(parent);1213        try {14            source.subscribe(parent);15        } catch (Throwable ex) {16            Exceptions.throwIfFatal(ex);17            parent.onError(ex);18        }19    }

ObservableCreate 其实也很简单,它是 Observable 的子类,持有了上游 source 的引用,并重写 subscribeActual 方法。

接下来我们来看重点了,即 Observable 的 subscribe 方法,在该方法中,他会将 Observalble 与 observer 关联起来。

 1@SchedulerSupport(SchedulerSupport.NONE) 2@Override 3public final void subscribe(Observer<? super T> observer) { 4    // 检查 observer 是否为 null,为 null 抛出异常 5    ObjectHelper.requireNonNull(observer, "observer is null"); 6    try { 7       // RxJavaPlugins 插件的,暂时不管 8        observer = RxJavaPlugins.onSubscribe(this, observer); 91011      // 检查 observer 是否为 null,为 null 抛出异常12        ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");1314        subscribeActual(observer);15    } catch (NullPointerException e) { // NOPMD16        throw e;17    } catch (Throwable e) {18        Exceptions.throwIfFatal(e);19        // can't call onError because no way to know if a Disposable has been set or not20        // can't call onSubscribe because the call might have set a Subscription already21        RxJavaPlugins.onError(e);2223        NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");24        npe.initCause(e);25        throw npe;26    }27}

subscribe 方法也比较简单,大概可以分为以下两步:

  • 首先检查 observer 是否为空,为 null 抛出异常

  • 第二步,调用 subscribeActual 方法,而我们知道在 Observable 类中 subscribeActual 是抽象方法,因此,我们只需要关注其实现类的 subscribeActual 方法。从上面的分析,我们知道,当我们调用 Observable

    create(ObservableOnSubscribe source) 方法的时候,最终会返回 ObservableCreate 实例。因此,我们只需要关注 ObservableCreate 的 subscribeActual 方法
 1public final class ObservableCreate<T> extends Observable<T> { 2    final ObservableOnSubscribe<T> source; 3 4    public ObservableCreate(ObservableOnSubscribe<T> source) { 5        this.source = source; 6    } 7 8    @Override 9    protected void subscribeActual(Observer<? super T> observer) {10        CreateEmitter<T> parent = new CreateEmitter<T>(observer);11        observer.onSubscribe(parent);1213        try {14            source.subscribe(parent);15        } catch (Throwable ex) {16            Exceptions.throwIfFatal(ex);17            parent.onError(ex);18        }19    }2021    ----22}

ObservableCreate 的核心代码主要也只有几行,source 是上游 ObservableOnSubscribe 的引用,而 CreateEmitter 这个类,它是 ObservableCreate 的一个静态内部类,实现了 ObservableEmitter,Disposable 接口 它持有 observer 的引用,当我们调用 CreateEmitter 的 next 方法的时候,它会判断当前的 CreateEmitter 有没有被 dispose 掉,如果没有,调用他持有的 observer 的 onNext 方法, 同理 onComplete 方法一一样,只不过执行完 onComplete 方法的时候,还会执行 dispose 方法,dispose 当前的 CreateEmitter。(dispose 方法这里先记住以下,下面会讲到

 1static final class CreateEmitter<T> 2extends AtomicReference<Disposable> 3implements ObservableEmitter<T>, Disposable { 4 5 6    private static final long serialVersionUID = -3434801548987643227L; 7 8    final Observer<? super T> observer; 910    CreateEmitter(Observer<? super T> observer) {11        this.observer = observer;12    }1314    @Override15    public void onNext(T t) {16        if (t == null) {17            onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));18            return;19        }20        if (!isDisposed()) {21            observer.onNext(t);22        }23    }2425    @Override26    public void onError(Throwable t) {27        if (!tryOnError(t)) {28            RxJavaPlugins.onError(t);29        }30    }3132    @Override33    public boolean tryOnError(Throwable t) {34        if (t == null) {35            t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");36        }37        if (!isDisposed()) {38            try {39                observer.onError(t);40            } finally {41                dispose();42            }43            return true;44        }45        return false;46    }4748    @Override49    public void onComplete() {50        if (!isDisposed()) {51            try {52                observer.onComplete();53            } finally {54                dispose();55            }56        }57    }5859    @Override60    public void setDisposable(Disposable d) {61        DisposableHelper.set(this, d);62    }6364    @Override65    public void setCancellable(Cancellable c) {66        setDisposable(new CancellableDisposable(c));67    }6869    @Override70    public ObservableEmitter<T> serialize() {71        return new SerializedEmitter<T>(this);72    }7374    @Override75    public void dispose() {76        DisposableHelper.dispose(this);77    }7879    @Override80    public boolean isDisposed() {81        return DisposableHelper.isDisposed(get());82    }83}

好,看完上面的代码,我们回到 ObservableCreate 的 subscribeActual 方法,我们调用 observer.onSubscribe 方法的时候,会将 parent 对象作为方法参数暴露出去(而这个 parent 正是我们的 CreateEmitter,通过 CreateEmitter 的 dispose 方法可以取消订阅关系)。接着,当我们调用 source.subscribe(parent) 的时候,会调用 ObservableOnSubscribe 的 subscribe 方法。

1    CreateEmitter<T> parent = new CreateEmitter<T>(observer);2    observer.onSubscribe(parent);34    try {5        source.subscribe(parent);6    } catch (Throwable ex) {7        Exceptions.throwIfFatal(ex);8        parent.onError(ex);9    }

因此,在我们上面的例子中,若不出错,调用顺序

Observable subcrible > Observable subscribeActual > ObservableCreate subscribeActual > observer.onSubscribe > ObservableOnSubscribe subscribe(emitter 是 CreateEmitter 的实例,包装了 observer,调用 emitter 的相应方法 ,会进而调用 observer 的 onNext onComplete 方法,而不会调用 onError 方法)

若在调用 onNext 方法的过程中出错,那调用顺序可能是这样的

Observable subcrible > Observable subscribeActual > ObservableCreate subscribeActual > observer.onSubscribe > ObservableOnSubscribe subscribe(@NonNull ObservableEmitter  emitter)(emitter 是 CreateEmitter 的实例,包装了 observer,调用 emitter 的相应方法 ,会进而调用 observer 的 onNext onError 方法,而不会调用 onComplete 方法 )

observable 与 Observer 是如何取消订阅关系的

在上面讲解的时候,其实我们已经有提到 CreateEmitter 的 dispose 方法,该方法就是用来取消订阅关系的。

假设这样一个场景,当我们收到的 value 的值大于等于 2 的时候,这个时候认为是异常的,解决两者之间的订阅关系

 1    Observable<Integer> observable=Observable.create(new ObservableOnSubscribe<Integer>() { 2 3            @Override 4            public void subscribe(ObservableEmitter<Integer> e) throws Exception { 5                e.onNext(1); 6                e.onNext(2); 7                e.onNext(3); 8                e.onNext(4); 9                e.onComplete();10            }11        });1213    Observer<Integer> observer = new Observer<Integer>() {14            private Disposable disposable;1516            @Override17            public void onSubscribe(Disposable d) {18                disposable = d;19            }2021            @Override22            public void onNext(Integer value) {23                Log.d("xujun", value.toString());24                if (value >=2) {   // >=2  时为异常数据,解除订阅25                    disposable.dispose();26                }27            }2829            @Override30            public void onError(Throwable e) {3132            }3334            @Override35            public void onComplete() {36373839            }40        };4142    observable.subscribe(observer); //建立订阅关系

总结

Rxjava 的原理其实不难,Observable 和 Observer 通过 subscribe() 方法实现订阅关系,从而 Observable 可以在需要的时候发出事件来通知 Observer,并且回调 Observer 的相应的方法。

用一张简单的流程图描述如下:

下一篇博客,将会讲解到 Rxjava 的线程切换问题,敬请期待。

推荐阅读

装饰者模式及其应用

自定义 behavior - 完美仿 QQ 浏览器首页,美团商家详情页

技术人的未来在哪里

致刚入职场的你 - 程序员的成长笔记

Android 技术人

扫一扫,欢迎关注我的公众号。如果你有好的文章,也欢迎你的投稿。