RxJava2源码分析(上):架构解析

目录

 

一、概述

二、观察者模式

三、Rxjava2简单使用

四、源码分析

1、创建被观察者

2、创建观察者

3、subscribe()

五、总结


一、概述

    Rxjava2作为一个异步操作库,在进行耗时任务时,给我们提供了非常方便的、逻辑简洁的操作。这篇文章咱们来仔细分析Rxjava2的源码,了解它内部的实现原理。

    说明:本文分析的Rxjava2版本为2.1.9。

 

二、观察者模式

    在分析Rxjava2源码之前,咱们先来看Rxjava2中的一个核心设计模式:观察者模式。

    所谓观察者模式,就是A对象对B对象的数据非常敏感,当B对象的数据改变时,A对象马上做出响应,这就是观察者模式,此时B对象为被观察者,A对象则为观察者。在Android开发中经常遇到这种情况:发送网络请求获取数据,当数据成功返回时,UI马上进行更新显示该数据,这也是一种观察者模式。而Rxjava2框架,就是采用观察者模式。

 

三、Rxjava2简单使用

...
    private void rxjavaTest(){
        //1.创建被观察者
        Observable observable =Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter emitter) throws Exception {
                System.out.println("开始发射数据1");
                emitter.onNext("发射数据1");
                System.out.println("开始发射数据2");
                emitter.onNext("发射数据2");
            }
        });

        //2.创建观察者
        Observer observer = new Observer() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Object o) {
                System.out.println("接收到数据:" + o);
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        };
        //3.被观察者订阅观察者
        observable.subscribe(observer);
    }
...

    代码执行后的打印结果:

开始发射数据1
接收到数据:发射数据1
开始发射数据2
接收到数据:发射数据2

    这里需要说明一下,在普通的观察者模式中,是观察者订阅被观察者,从而将两者关联起来。但是在Rxjava2中,也就是举例的第3步中是被观察者订阅了观察者,这样做是为了方便开发者采用链式调用的方式使用Rxjava2,不必过于纠结。关于Rxjava2的链式调用,咱们后面分析。

 

四、源码分析

1、创建被观察者

    首先来看看被观察者Observable类:

public abstract class Observable<T> implements ObservableSource<T> {
...
}

这是一个抽象类,实现自ObservableSource。

    在上面栗子中:

Observable observable = Observable.create(new ObservableOnSubscribe() {
    @Override
    public void subscribe(ObservableEmitter emitter) throws Exception {
    }
});

可以看到,创建被观察者调用的是Observable类的create方法,并需要传入一个ObservableOnSubscribe实例对象,跟进去看create方法:

...
    @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));
    }
...

该方法首行是负责验证参数是否为空并抛出空指针异常,咱们需要注意的是第二行代码:

return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));

这行代码表示返回一个RxJavaPlugins.onAssembly的值,这个值就是一个Observable实例对象,看传入的参数类:

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

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

可以看到ObservableCreate实现了Observable接口,至于ObservableCreate类内部的具体逻辑,暂时先不用管。RxJavaPlugins.onAssembly()方法中传入了一个ObservableCreate实例对象,接着看RxJavaPlugins.onAssembly():

...
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @NonNull
    public 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;
    }
...

这是一个hook实现,关于hook,可以理解为这是一个抽象代理,这个代理默认情况下不会对咱们的形参Observable做任何的处理,但是如果开发者想要对Observable做处理,可以调用RxJavaPlugins的SetonObservableAssembly()设置开发者自己实现的代理,从而替换原Observable,最后真正返回的是Observable的实现类ObservableCreate类的实例对象。在这里咱们没做任何处理,所以返回默认的Observable实现类ObservableCreate。至此创建完了一个被观察者对象Observable。

 

2、创建观察者

     先来看Observer:

public interface Observer<T> {

    void onSubscribe(@NonNull Disposable d);

    void onNext(@NonNull T t);

    void onError(@NonNull Throwable e);

    void onComplete();
}

看到Observer是一个接口,内部实现也很简单,提供了几个暴露给开发者的接口方法。

    现在看上面栗子中创建观察者的方式:

Observer observer = new Observer() {
    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onNext(Object o) {
        System.out.println("接收到数据:" + o);
    }

    @Override
    public void onError(Throwable e) {

    }

    @Override
    public void onComplete() {

    }
};

直接new了一个Observerz接口对象。基本整个创建被观察者的过程都很好理解。

 

3、subscribe()

    这个方法就是被观察者订阅观察者的调用方法,栗子中的实现是:

observable.subscribe(observer);

来看subscribe的代码:

public abstract class Observable<T> implements ObservableSource<T> {
...
    @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");
            //具体的订阅实现方法,该方法为Observable类的抽象方法,具体实现在其子类
            subscribeActual(observer);
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);

            RxJavaPlugins.onError(e);

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

ObjectHelper.requireNonNull(observer, "observer is null")和RxJavaPlugins.onSubscribe(this, observer)这两个方法和创建被观察者时候一样的功能,分别负责验空和代理。咱们看主要的代码subscribeActual(observer),该方法为Observable类的抽象方法,具体实现在其子类,也就是ObservableCreate类:

public final class ObservableCreate<T> extends Observable<T> {
...
    @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是ObservableCreate的内部类,用于适配被观察者中的事件发射器,最后的数据操作将交给这个类来处理。observer.onSubscribe(parent)作用是将该发射器类和观察者产生订阅关系,两者关联起来。

    source.subscribe(parent)中source就是在创建被观察者对象时传入的ObservableOnSubscribe对象实例,调用其subscribe方法,将上游事件发送对象(ObservableOnSubscribe)和下游接收对象(Observer)关联起来。

    在上面的栗子中,ObservableOnSubscribe即:

new ObservableOnSubscribe() {
    @Override
    public void subscribe(ObservableEmitter emitter) throws Exception {
        System.out.println("开始发射数据1");
        emitter.onNext("发射数据1");
        System.out.println("开始发射数据2");
        emitter.onNext("发射数据2");
    }
});

Observer又订阅了parent,即CreateEmitter,所以最后上游发射的事件将交由CreateEmitter处理:

    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;
            }
            //如果isDisposed为false,就将事件交由观察者对象,在这里就是咱们代码中new的observer对象
            if (!isDisposed()) {
                observer.onNext(t);
            }
        }

        @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()) {
                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 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());
        }
    }

如果isDisposed为false,就将事件交由观察者对象,在这里就是咱们代码中new的observer对象。

 

五、总结

    至此最简单的Rxjava2流程分析完成,可以看到逻辑还是很简单清晰的,当然代码量肯定不止咱们分析的这么点,还是那句话,看源码要抓住主干,将流程弄清楚,就简单了。

    上面代码不涉及到RxJava2的操作符,也没使用到RxJava2的线程控制,这样使用RxJava2框架是没有灵魂的,因此咱们接下来将代码升级。在接下来第二篇分析RxJava2框架源码的文章里,咱们将讲解RxJava2中的操作符和线程调度,传送门:RxJava2源码分析(下):操作符和线程调度https://blog.csdn.net/qq_29152241/article/details/82598506

                  

    关注我的博客和github,有大量福利哟~

    csdn博客:https://blog.csdn.net/qq_29152241

    github:https://github.com/cozing

 

 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值