RxJava2.x源码分析(一)

 

目录

 

目标

1 RxJava2分发订阅流程

2 RxJava2.x的随意取消订阅流程的原理


目标

学习完本系列内容,主要了解一下内容:

① 初步了解RxJava2.x的使用流程;

② 探索Observable发送数据的流程;

③ 明白Observer是如何接收数据的;

④ 解析Observable和Observer如何关联的过程;

⑤ 探索RxJava线程切换的奥秘;

⑥ 了解RxJava操作符的实现原理。

1 RxJava2分发订阅流程

从一个Demo案例开始讲解:

 /**观察者创建Observer**/
        Observer observer = new Observer() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.e(TAG,"onSubscribe");
            }

            @Override
            public void onNext(Object o) {
                Log.e(TAG,"onNext data is >>" + o);
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "onError data is >>" + e.toString());
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "onComplete");
            }
        };

        Observable observable = Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter e) throws Exception {
                e.onNext("hello");
                e.onNext("RxJava2.x");
                e.onComplete();
            }
        });
        /**订阅**/
        observable.subscribe(observer);

打印Log日志结果:

由Log日志可以发现,Observer的onSubscribe是最先被调用的。

RxJava的整个流程是从create开始的,我们就从create方法开始进行分析,create方法返回一个Observable对象,也就是被观察者对象,create方法需要需要传入一个ObservableOnSubscribe,首先我们先看下ObservableOnSubscribe的作用:

/**
 * A functional interface that has a {@code subscribe()} method that receives
 * an instance of an {@link ObservableEmitter} instance that allows pushing
 * events in a cancellation-safe manner.
 *
 * @param <T> the value type pushed
 */
public interface ObservableOnSubscribe<T> {

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

该接口会接收一个ObservableEmitter的一个对象,通过该对象我们可以发送消息可可以安全的取消消息,接着往里看ObservableEmitter这个接口类:

/**
 * Abstraction over an RxJava {@link Observer} that allows associating
 * a resource with it.
 * <p>
 * The onNext, onError and onComplete methods should be called
 * in a sequential manner, just like the Observer's methods.
 * Use {@link #serialize()} if you want to ensure this.
 * The other methods are thread-safe.
 *
 * @param <T> the value type to emit
 */
public interface ObservableEmitter<T> extends Emitter<T> {

    /**
     * Sets a Disposable on this emitter; any previous Disposable
     * or Cancellation will be unsubscribed/cancelled.
     * @param d the disposable, null is allowed
     */
    void setDisposable(Disposable d);

    /**
     * Sets a Cancellable on this emitter; any previous Disposable
     * or Cancellation will be unsubscribed/cancelled.
     * @param c the cancellable resource, null is allowed
     */
    void setCancellable(Cancellable c);

    /**
     * Returns true if the downstream disposed the sequence.
     * @return true if the downstream disposed the sequence
     */
    boolean isDisposed();

    /**
     * Ensures that calls to onNext, onError and onComplete are properly serialized.
     * @return the serialized ObservableEmitter
     */
    ObservableEmitter<T> serialize();
}

ObservableEmitter是对Emitter的扩展,而扩展的方法证实了RxJava2.x引入,提供了可中途取消等新功能,继续分析Emitter:

/**
 * Base interface for emitting signals in a push-fashion in various generator-like source
 * operators (create, generate).
 *
 * @param <T> the value type emitted
 */
public interface Emitter<T> {

    /**
     * Signal a normal value.
     * @param value the value to signal, not null
     */
    void onNext(T value);

    /**
     * Signal a Throwable exception.
     * @param error the Throwable to signal, not null
     */
    void onError(Throwable error);

    /**
     * Signal a completion.
     */
    void onComplete();
}

里面的三个方法很眼熟,到这里,我们了解传参数的数据结构,接下来继续探索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));
    }

首先对传入的source进行非空判断,我们传入ObservableOnSubscribe被用来创建ObservableCreate,ObservableCreate其实就是Observable的一个实现类。

思路捋一捋

a) Observable通过调用create创建一个Observable;

b) 调用create需要传递一个ObservableOnSubscribe类型的实例参数;

c) ObservableOnSubscribe类型的实例参数作为ObservableCreate构造函数的参数传入,一个Observable就此产生。

 

接下来查看ObservableCreate,首先查看ObservableCreate的两个方法:

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

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

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

source为Observable.create传入的ObservableOnSubscribe实例:

subscribeActual回调方法,它在调用Observable.subscribe时被调用,即与观察者或者被观察者发生联系时触发,subscribeActual是实现我们主要的逻辑的地方,因此比较重要,接下来我们仔细分析subscribeActual方法:

1) 首先subscribeActual传入的参数类型为Observer类型,也就是在subscribe时传入的观察者,后面会分析到;

2) 传入的Observer会被包装成一个CreateEmitter,CreateEmitter是一个继承了AtomicReference提供了原子级的控制能力,RxJava2.x提供的新特性与之息息相关,后面进行分析;

3) 观察者(observer)调用自己的observer.onSubscribe(parent);将包装后的observer传入,这也是RxJava2.x的变化,真正的鼎业是在source.subscribe(parent)这句代码执行之后开始的,而之前先调用了onSubscribe方法用来提供RxJava2.x后引入的新能力(如中断),在此处我们就能明白为何观察者的onSubscribe最先被调用了。

4) 被订阅者或者说被观察者(source)调用subscribe订阅方法与观察者发生联系,这里进行异常捕获,如果subscribe抛出了未被捕获的异常,则调用parent.onError(ex);

5) 执行subscribe时也就对应了Demo中的代码:

Observable observable = Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter e) throws Exception {
                e.onNext("hello");
                e.onNext("RxJava2.x");
                e.onComplete();
            }
        });

看来subscribeActual这个回调确实很重要,前面说了subscribeActual回调方法在Observable.subscribe被调用时执行的,我们来进行分析一波:

@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");

            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;
        }
    }

可以看到RxJavaPlugins.onSubscribe(this, observer);,我们RxJava2.0中的Hook能力就是来自这里了。然后继续看下面subscribeActual(observer);被调用了。

思路捋一捋

a) 传入的ObservableOnSubscribe最终被用来创建成ObservableCreate;

b) ObservableCreate持有我们被观察者对象以及订阅时所触发的subscribeActual;

c) 在subscribeActual中实现了我们的主要逻辑,包括observer.onSubscribe(parent);,source.subscribe(parent);,parent.onError(ex);的调用;

d) 在Observable的subscribe被调用时,开始执行事件分发流程。

2 RxJava2.x的随意取消订阅流程的原理

前面初步分析了RxJava从创建到执行的流程;

接下来我们探索RxJava2.x提供的Disposable的能力:

老规矩,先看一个Demo实例

/**观察者创建Observer**/
        Observer observer = new Observer() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.e(TAG,"onSubscribe");
                disposable = d;
            }

            @Override
            public void onNext(Object o) {
                Log.e(TAG,"onNext data is >>" + o);
                if(o.equals("hello")){
                    //执行了hello之后结束
                    disposable.dispose();
                }
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "onError data is >>" + e.toString());
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "onComplete");
            }
        };

        Observable observable = Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter e) throws Exception {
                e.onNext("hello");
                Log.e(TAG,"发送了hello");
                e.onNext("RxJava2.x");
                Log.e(TAG,"发送了RxJava2.x");
                e.onComplete();
                Log.e(TAG,"发送了onComplete");
            }
        });
        /**订阅**/
        observable.subscribe(observer);
    }

执行结果:

在发送完成hello之后,成功地终止了后续的Reactive流,从结果可以看出,后面的Reactive流被终止了,也就是订阅者或者说观察者接收不到了,但是被订阅者,被观察者的代码还是会执行的。

我们从disposable.dispose();方法开始入手,因为触发的该事件之后,就接收不到了,查看源码:

public interface Disposable {
    /**
     * Dispose the resource, the operation should be idempotent.
     */
    void dispose();

    /**
     * Returns true if this resource has been disposed.
     * @return true if this resource has been disposed
     */
    boolean isDisposed();
}

回顾前面所讲的一段代码

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

@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);
    }
}
  • 我们之前分析在执行source.subscribe(parent);触发数据分发事件之前先执行了observer.onSubscribe(parent)这句代码,所传入的parent也就对应了我们的Disposable;
  • parent是CreateEmitter类型的,但是CreateEmitter是一个实现了Disposable接口的一个类,而parent又是我们经过包装后的对象;
  • 分析到这里,整理下前面的环节,根据Demo解释下:首先在执行下面代码之前:
e.onNext("hello");
Log.e(TAG,"发送了hello");
e.onNext("RxJava2.x");
Log.e(TAG,"发送了RxJava2.x");
e.onComplete();
Log.e(TAG,"发送了onComplete");
  • 先执行了observer.onSubscribe(parent);在Demo中也是通过传入parent调用其dispose方法来终止Reactive流,而执行分发hello等数据的e也是我们的parent,他们都是同一个对象,而执行e.onNext("hello");中的e对象也是observer的一个包装后的ObservableEmitter类型的对象。

接下来我们查看关键点CreateEmitter parent = new CreatEmitter(observer);这个包装的过程,分析其源码:

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;
            }
            if (!isDisposed()) {
                observer.onNext(t);
            }
        }

        @Override
        public void onError(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();
                }
            } else {
                RxJavaPlugins.onError(t);
            }
        }

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

CreateEmitter是ObservableCreate类的静态内部类,CreateEmitter实现了ObservableEmitter,Disposable接口类,所以需要实现其方法,这里使用了装饰者模式。

我们可以看到在ObservableEmitter内部通过Observer<? super T> observer存储了我们的observer,如此做法的目的又是什么呢?

通过查看Demo,我们在调用e.onNext("hello");时,调用的是ObservableEmitter对象的onNext方法,然后ObservableEmitter对象的onNext方法内部再通过observer调用onNext方法,但是从源码发现,并不是简单的进行调用:

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

首先会判断传入的数据是否为null;

其次判断isDisposed(),如果!isDisposed()返回false,则不执行onNext();

isDisposed()什么时候会返回false?就是我们在调用了disposable.dispose()后,disposable前面分析了就是CreateEmitter parent,查看CreateEmitter.dispose()

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

 

里面调用了DisposableHelper.dispose(this);,我们看isDisposed()

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

RxJava的onComplete();与onError(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();
                }
            }
        }

其内部也做了同样的判断,!isDisposed()后再决定是否执行;

我们知道onComplete()和onError(t)方法只有一个会发生,其原理也是通过isDisposed()这个方法,不管是先执行onComplete(),还是先执行onError(t),最终都会调用dispose(),而调用了dispose()以后,isDisposed()为false,就不会再去执行另外一个了,而且如果认为先调用onComplete再调用onError,onComplete不会被触发,而且会抛出NullPointerException异常。

通过以上内容我们知道了Reactive流如何被终止以及RxJava的onComplete()与onError(t),只有一个会被执行的原因;

接下来探究下DisposableHelper这个类,代码里面两个静态方法的作用:

public enum DisposableHelper implements Disposable {
 DISPOSED;

 public static boolean isDisposed(Disposable d) {
   // 判断上次记录的终点标识的是否是 当前执行的Observer,如果是返回true
    return d == DISPOSED;
}
....
public static boolean dispose(AtomicReference field) {
    //1、current为我们当前的observer的Disposable的值,第一次调用时current是null
    Disposable current = field.get();
    //2、终止标识
    Disposable d = DISPOSED;
    //3、两次不相同,说明observer未调用过dispose,
    if (current != d) {
        //4、将终止标识的值设置給当前的observer的Disposable,并返回设置前的observer的Disposable的值,此时如果调用isDisposed(Disposable d)返回的就是ture了
        current = field.getAndSet(d);
        if (current != d) {
            //第一次调用时会走到这里,此时current==null,返回true,
            //current不为null时说明当前的observer调用了多次dispose(),而如果多次调用了Disposable的值还不是DISPOSED,说明之前设置失败,所以再次调用dispose();
            if (current != null) {
                current.dispose();
            }
            return true;
        }
    }
    return false;
}
....
}    
  • DISPOSED:作为是否要终止的枚举类型的标识;
  • isDisposed:判断上次记录的终点标识的是否是 当前执行的Observer,如果是返回true;
  • dispose:采用了原子性引用类AtomicReference,目的是防止多线程操作出现的错误。

思路捋一捋

  • 了解了RxJava的随意终止Reactive流的能力的来源;
  • 明白了RxJava的onComplete();与onError(t);只有一个会被执行的秘密;
  • 实现该能力的主要方式还是利用了装饰者模式;
  • 我们还接触了AtomicReference这个类,在平时估计很少接触到。

 

下篇  RxJava2.x源码分析(二)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值