RxJava部分源码解析

RxJava2.x 部分源码解析

这几天比较空闲所以准备也做一个仿知乎日报的APP,然后就想到几个比较好用的框架顺便也好好练练手,就准备用Retrofit+RxJava来实现基本网络请求和事件处理的框架。在使用的时候就顺便研究了源码,汲取下这些优秀的开源框架的设计模式和思想。这篇文章就主要记录一下在看RxJava2.x部分源码的过程。

简单用法

Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter e) throws Exception {
                e.onNext("1");
            }
        }).subscribe(new Observer() {
            //这里的d实际上是前面subscribe方法中的e
            @Override
            public void onSubscribe(Disposable d) {
            }

            @Override
            public void onNext(String value) {
                Log.d("WH", value + Thread.currentThread());
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("error");
            }

            @Override
            public void onComplete() {
                System.out.println("complete");
            }
        });

这段代码是RxJava最简单的一种使用,主要是==create==和==subscribe==两个方法,首先进入看下这两个方法

public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        ObjectHelper.requireNonNull(source, "source is null");
        return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
    }
public final void subscribe(Observersuper T> observer) {
        ObjectHelper.requireNonNull(observer, "observer is null");
        try {
            observer = RxJavaPlugins.onSubscribe(this, observer);

            ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
            //这个方法才是真正订阅发生的地方
            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);

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

可以看到总体来说就是create方法返回了一个Observable对象,然后就调用这个对象的subscribe方法,根据subscribe方法实现,很显然subscribeActual(observer)这个方法才是重点,真正的绑定实际上是发生在这里的,他的名字也很好的体现了这一点。所以就先看一下==RxJavaPlugins.onAssembly(new ObservableCreate(source));==,这里我觉得是使用了适配器模式将ObservableOnSubscribe对象转换为所需的Observable对象,先看onAssembly方法。

/**
     * Calls the associated hook function.
     * @param  the value type
     * @param source the hook's input value
     * @return the value returned by the hook
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static  Observable onAssembly(Observable source) {
        Function f = onObservableAssembly;
        if (f != null) {
            return apply(f, source);
        }
        //这里因为我是使用的最简单的用法所以其实f为null,所以source就原样返回了
        return source;
    }

这个传入的是一个Observable对象,事实上ObservableCreate类也的确是继承于Observable的,此处我特地将源码的注释放上来了,因为关于hook我暂时还没搞懂,但是这里是直接返回source的,没有经过处理,所以也就是直接返回的==RxJavaPlugins.onAssembly(new ObservableCreate(source));==中的new ObservableCreate(source)这个对象,现在就进入到ObservableCreate类中好好看一看吧。

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

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

    @Override
    protected void subscribeActual(Observer super T> observer) {
        CreateEmitter parent = new CreateEmitter(observer);
        //此处我们可以看出其实在observe实现类中的disposed参数对象就是这个emitter对象,他实现了disposable接口
        observer.onSubscribe(parent);

        try {
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

这个source就是create方法中传入的匿名内部类,然后重点来了,上面提到的subscribe方法中的subscribeActual方法真正实现,就在这里,这里又引进了一个新的类==CreateEmitter==,根据这个方法中的内容大概也能猜出来了,parent这个对象起到的是一个枢纽作用,连接起观察者(Observer对象)和被观察者(Observable对象)。这里调用的==onSubscribe==和===subscribe==方法就是我上面写的demo中的两个方法,也是真正的事件发生地点,那么就看看这个CreateEmitter呗,

static final class CreateEmitter<T>
    extends AtomicReference<Disposable>
    implements ObservableEmitter<T>, Disposable {

        private static final long serialVersionUID = -3434801548987643227L;

        final Observersuper T> observer;

        CreateEmitter(Observersuper T> observer) {
            this.observer = observer;
        }

        @Override
        public void onNext(T t) {
            if (!isDisposed()) {
                observer.onNext(t);
            }
        }

        @Override
        public void onError(Throwable t) {
            if (!isDisposed()) {
                try {
                    observer.onError(t);
                } finally {
                    dispose();
                }
            } else {
                RxJavaPlugins.onError(t);
            }
        }

        @Override
        public void onComplete() {
            if (!isDisposed()) {
                try {
                    observer.onComplete();
                } finally {
                    dispose();
                }
            }
        }

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

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

果然是这样,根据CreateEmitter对象实际上调用的是observer对象的方法,这里运用的是代理模式嘛,说实话代理模式装饰模式分不太清,反正就是Emitter作为一个中间类,上接被观察者,下连观察者。
然后还有比较重要的Disposable这个对象,可以直接中断事件传递,然后我们onSubscribe方法把这个对象传过去,实际上就是emitter对象。这也是为什么当我们调用Disposable对象的dispose方法后,后面的事件observe就不会再接收到了。也是为什么onComplete或者onError事件触发后后面的事件不会再触发,因为在emitter这个中间者这里已经处理了。
RxJava部分源码解析_第1张图片

总结

基本的简单流程就是这样,我也是刚刚开始用RxJava,所以就分析了最简单的使用场景,后面有机会会分析带线程调度的用法的。

  1. 在subscribeActual()方法中,源头和终点关联起来。
  2. source.subscribe(parent);这句代码执行时,才开始从发送ObservableOnSubscribe中利用ObservableEmitter发送数据给Observer。即数据是从源头push给终点的。
  3. CreateEmitter 中,只有Observable和Observer的关系没有被dispose,才会回调Observer的onXXXX()方法
  4. Observer的onComplete()和onError()互斥只能执行一次,因为CreateEmitter在回调他们两中任意一个后,都会自动dispose()。根据上一点,验证此结论。
  5. 先error后complete,complete不显示。 反之会crash
  6. 还有一点要注意的是onSubscribe()是在我们执行subscribe()这句代码的那个线程回调的,并不受线程调度影响。

本片博文也是参考这位博主来分析的直达连接

你可能感兴趣的:(android学习)