RxJava(2.0)-订阅源码分析

基于RxJava 2.0+版本,对RxJava的订阅源码进行简单分析。

1. 使用实例

我们在使用RxJava2.0时,一般像下面这样使用。

    //1.创建被观察者
    val flowable = Flowable.create(object : FlowableOnSubscribe<String> {
        @Throws(Exception::class)
        override fun subscribe(e: FlowableEmitter<String>) {
            e.onNext("Hello")
            e.onNext("World")
            e.onNext("!")
            //注意在此调用onComplete方法结束事件的处理
            e.onComplete()
        }
    }, BackpressureStrategy.BUFFER)

    // 2.创建观察者
    val subscriber = object : Subscriber<String> {
        override fun onSubscribe(s: Subscription) {
            println("onSubscribe")
            // 不调用方法,无法发送流。
            s.request(Long.MAX_VALUE)
        }

        override fun onNext(s: String) {
            println(s)
        }

        override fun onError(t: Throwable) {
            t.printStackTrace()
        }

        override fun onComplete() {
            println("onComplete")
        }
    }

    // 3.订阅
    flowable.subscribe(subscriber)

以上代码基于Kotlin实现,Java实现方式基本类似。

2. 源码分析

2.1 创建被观察者

  //1.创建被观察者
    val flowable = Flowable.create(object : FlowableOnSubscribe<String> {

        // 1. 方法在产生订阅关系后被调用
        @Throws(Exception::class)
        override fun subscribe(e: FlowableEmitter<String>) {
            // 使用发射器发送事件
            e.onNext("Hello")
            e.onNext("World")
            e.onNext("!")
            //注意在此调用onComplete方法结束事件的发送
            e.onComplete()
        }
    }, BackpressureStrategy.BUFFER)

FlowableOnSubscribe

public interface FlowableOnSubscribe<T> {

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

FlowableOnSubscribe接口在发生调阅关系时被调用,用于控制处理、发送事件。

FlowableEmitter

事件发射器,可以调用其接口来发送事件。

public interface FlowableEmitter<T> extends Emitter<T> {

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

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

    /**
     * The current outstanding request amount.
     * <p>This method is thread-safe.
     * @return the current outstanding request amount
     */
    long requested();

    /**
     * Returns true if the downstream cancelled the sequence or the
     * emitter was terminated via {@link #onError(Throwable)}, {@link #onComplete} or a
     * successful {@link #tryOnError(Throwable)}.
     * <p>This method is thread-safe.
     * @return true if the downstream cancelled the sequence or the emitter was terminated
     */
    boolean isCancelled();

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

    /**
     * Attempts to emit the specified {@code Throwable} error if the downstream
     * hasn't cancelled the sequence or is otherwise terminated, returning false
     * if the emission is not allowed to happen due to lifecycle restrictions.
     * <p>
     * Unlike {@link #onError(Throwable)}, the {@code RxJavaPlugins.onError} is not called
     * if the error could not be delivered.
     * @param t the throwable error to signal if possible
     * @return true if successful, false if the downstream is not able to accept further
     * events
     * @since 2.1.1 - experimental
     */
    @Experimental
    boolean tryOnError(@NonNull Throwable t);
}

Emitter

public interface Emitter<T> {

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

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

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

这个才是真正发送数据的接口定义。

Flowable.Create

   public static <T> Flowable<T> create(FlowableOnSubscribe<T> source, BackpressureStrategy mode) {
        ObjectHelper.requireNonNull(source, "source is null");
        ObjectHelper.requireNonNull(mode, "mode is null");
        return RxJavaPlugins.onAssembly(new FlowableCreate<T>(source, mode));
    }

根据FlowableOnSubscribe、背压策略构造并返回FlowableCreate实例。

RxJavaPlugins.onAssembly

   public static <T> Flowable<T> onAssembly(@NonNull Flowable<T> source) {
        Function<? super Flowable, ? extends Flowable> f = onFlowableAssembly;
        if (f != null) {
            return apply(f, source);
        }
        return source;
    }

如果设置了相关的转换方法,则调用,否则返回传入的Flowable。

FlowableCreate-实际创建的对象

  1. FlowableCreate继承于Flowable。
  2. 会根据背压模式创建不同的发射器,用于订阅时的回调。
public final class FlowableCreate<T> extends Flowable<T> {

    final FlowableOnSubscribe<T> source;

    final BackpressureStrategy backpressure;

    public FlowableCreate(FlowableOnSubscribe<T> source, BackpressureStrategy backpressure) {
        this.source = source;
        this.backpressure = backpressure;
    }

    @Override
    public void subscribeActual(Subscriber<? super T> t) {
        BaseEmitter<T> emitter;

        switch (backpressure) {
        case MISSING: {
            emitter = new MissingEmitter<T>(t);
            break;
        }
        case ERROR: {
            emitter = new ErrorAsyncEmitter<T>(t);
            break;
        }
        case DROP: {
            emitter = new DropAsyncEmitter<T>(t);
            break;
        }
        case LATEST: {
            emitter = new LatestAsyncEmitter<T>(t);
            break;
        }
        default: {
            emitter = new BufferAsyncEmitter<T>(t, bufferSize());
            break;
        }
        }

        // 调用Subscriber的onSubscribe方法[onSubscribe(s: Subscription)]
        // emitter实际上继承了Subscription
        t.onSubscribe(emitter);
        try {
            // 调用FlowableOnSubscribe的subscribe方法[subscribe(e: FlowableEmitter<String>)]
            // emitter实际上继承了FlowableEmitter
            source.subscribe(emitter);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            emitter.onError(ex);
        }
    }
}

2.2 创建观察者

    // 定义观察者
    val subscriber = object : Subscriber<String> {
        override fun onSubscribe(s: Subscription) {
            println("onSubscribe")
            // 不调用方法,无法发送流。
            s.request(Long.MAX_VALUE)
        }

        override fun onNext(s: String) {
            println(s)
        }

        override fun onError(t: Throwable) {
            t.printStackTrace()
        }

        override fun onComplete() {
            println("onComplete")
        }
    }

Subscriber

public interface Subscriber<T> {
    /**
     * Invoked after calling {@link Publisher#subscribe(Subscriber)}.
     * <p>
     * No data will start flowing until {@link Subscription#request(long)} is invoked.
     * <p>
     * It is the responsibility of this {@link Subscriber} instance to call {@link Subscription#request(long)} whenever more data is wanted.
     * <p>
     * The {@link Publisher} will send notifications only in response to {@link Subscription#request(long)}.
     * 
     * @param s
     *            {@link Subscription} that allows requesting data via {@link Subscription#request(long)}
     */
    public void onSubscribe(Subscription s);

    /**
     * Data notification sent by the {@link Publisher} in response to requests to {@link Subscription#request(long)}.
     * 
     * @param t the element signaled
     */
    public void onNext(T t);

    /**
     * Failed terminal state.
     * <p>
     * No further events will be sent even if {@link Subscription#request(long)} is invoked again.
     *
     * @param t the throwable signaled
     */
    public void onError(Throwable t);

    /**
     * Successful terminal state.
     * <p>
     * No further events will be sent even if {@link Subscription#request(long)} is invoked again.
     */
    public void onComplete();
}


该接口主要是定义了事件处理方法,特别需要注意的几点:

  1. onSubscribe在发生订阅关系时首先被调用;
    除非在该方法中调用了Subscription.request方法,否则数据流不会发送;也可以在该方法中调用Subscription.cancel取消数据流的发送。

  2. onError与onComplete方法互斥。

  3. onNext接收事件并处理。

2.3 订阅


    // 3.订阅
    flowable.subscribe(subscriber)

Flowable.subscribe(Subscriber<? super T> s)



 public final void subscribe(Subscriber<? super T> s) {
        // 我们只实现了Subscriber接口,s为FlowableSubscriber实例
        if (s instanceof FlowableSubscriber) {
            // 实际调用的是subscribe(FlowableSubscriber<? super T> s)
            subscribe((FlowableSubscriber<? super T>)s);
        } else {
            ObjectHelper.requireNonNull(s, "s is null");
            subscribe(new StrictSubscriber<T>(s));
        }
    }


FlowableSubscriber


public interface FlowableSubscriber<T> extends Subscriber<T> {

    /**
     * Implementors of this method should make sure everything that needs
     * to be visible in {@link #onNext(Object)} is established before
     * calling {@link Subscription#request(long)}. In practice this means
     * no initialization should happen after the {@code request()} call and
     * additional behavior is thread safe in respect to {@code onNext}.
     *
     * {@inheritDoc}
     */
    @Override
    void onSubscribe(@NonNull Subscription s);
}

其实FlowableSubscriber与Subscriber的定义相同。

Flowable.subscribe(FlowableSubscriber<? super T> s)

public final void subscribe(FlowableSubscriber<? super T> s) {
        ObjectHelper.requireNonNull(s, "s is null");
        try {
            // 附加操作
            Subscriber<? super T> z = RxJavaPlugins.onSubscribe(this, s);

            ObjectHelper.requireNonNull(z, "Plugin returned null Subscriber");

            // 实际的实现在这里
            subscribeActual(z);
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            // can't call onError because no way to know if a Subscription 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;
        }
    }


Flowable.subscribeActual

protected abstract void subscribeActual(Subscriber<? super T> s)

这个方法为抽象方法,那么它的实际实现在哪里呢?答案就是我们在创建Flowable时分析的FlowableCreate。

FlowableCreate.subscribeActual

public final class FlowableCreate<T> extends Flowable<T> {

    // 1. 创建Flowable对象时传入的FlowableOnSubscribe实例
    final FlowableOnSubscribe<T> source;

    // 1. 创建Flowable对象时传入的背压策略
    final BackpressureStrategy backpressure;


    public FlowableCreate(FlowableOnSubscribe<T> source, BackpressureStrategy backpressure) {
        this.source = source;
        this.backpressure = backpressure;
    }

    @Override
    public void subscribeActual(Subscriber<? super T> t) {
        BaseEmitter<T> emitter;

        // 根据不同的背压策略,创建不同的发射器
        switch (backpressure) {
        case MISSING: {
            emitter = new MissingEmitter<T>(t);
            break;
        }
        case ERROR: {
            emitter = new ErrorAsyncEmitter<T>(t);
            break;
        }
        case DROP: {
            emitter = new DropAsyncEmitter<T>(t);
            break;
        }
        case LATEST: {
            emitter = new LatestAsyncEmitter<T>(t);
            break;
        }
        default: {
            // 我们创建的是这个
            emitter = new BufferAsyncEmitter<T>(t, bufferSize());
            break;
        }
        }

        // 1. 首先回调Subscriber的onSubscribe方法
        t.onSubscribe(emitter);
        try {
            // 2.回调FlowableOnSubscribe的subscribe方法
            // 我们一般在subscribe方法中发送数据
            source.subscribe(emitter);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            // 发生异常,则直接回调onError接口
            emitter.onError(ex);
        }
    }
}

BufferAsyncEmitter

BufferAsyncEmitter系FlowableCreate的静态内部类,Emitter设计为对外透明,用户只需设置背压策略即可。

static final class BufferAsyncEmitter<T> extends BaseEmitter<T> {


        private static final long serialVersionUID = 2427151001689639875L;

        final SpscLinkedArrayQueue<T> queue;

        Throwable error;
        volatile boolean done;

        final AtomicInteger wip;

        // 1. actual实际的订阅者。
        // 2. capacityHint默认值为128。
        BufferAsyncEmitter(Subscriber<? super T> actual, int capacityHint) {
            super(actual);
            this.queue = new SpscLinkedArrayQueue<T>(capacityHint);
            this.wip = new AtomicInteger();
        }


        // 我们在Flowable的subscribe方法,调用此接口来发送事件。
        @Override
        public void onNext(T t) {
            // 1. 当我们在Flowable.subscribe中调用onComplete方法后,done为true,事件不再发送
            // 2. 当我们在Flowable.subscribe调用cancel方法后,isCancelled返回true
            // 3. 当我们在Subscriber的onSubscribe方法调用Subsription.cancel方法后,isCancelled返回true
            if (done || isCancelled()) {
                return;
            }

            if (t == null) {
                onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
                return;
            }
            // 将事件加入队列
            queue.offer(t);
            drain();
        }

        @Override
        public boolean tryOnError(Throwable e) {
            if (done || isCancelled()) {
                return false;
            }

            if (e == null) {
                e = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
            }

            error = e;
            done = true;
            drain();
            return true;
        }

        // 我们在Flowable的subscribe方法调用该方法来结束事件发送
        @Override
        public void onComplete() {
            done = true;
            drain();
        }

        // 调用request方法后,该方法会被调用
        @Override
        void onRequested() {
            drain();
        }

        @Override
        void onUnsubscribed() {
            if (wip.getAndIncrement() == 0) {
                queue.clear();
            }
        }

        void drain() {
            // 当前正在进行事件分发,因为在onNext中已经将事件加入队列,直接返回
            if (wip.getAndIncrement() != 0) {
                return;
            }

            int missed = 1;
            final Subscriber<? super T> a = actual;
            final SpscLinkedArrayQueue<T> q = queue;

            // 进入循环进行事件分发
            for (;;) {
                // 1. 未调用request方法,r==0
                // 2. request方法,r==n
                long r = get();
                long e = 0L;

                // 只有调用了request方法,e!=r
                while (e != r) {
                    // 如果已经被取消,清空队列,直接返回
                    if (isCancelled()) {
                        q.clear();
                        return;
                    }

                    boolean d = done;

                    T o = q.poll();

                    boolean empty = o == null;

                    // 判断事件正常结束or异常
                    if (d && empty) {
                        Throwable ex = error;
                        if (ex != null) {
                            error(ex);
                        } else {
                            complete();
                        }
                        return;
                    }

                    if (empty) {
                        break;
                    }

                    // 事件不为空,分发事件
                    a.onNext(o);

                    e++;
                }

                // 1.如果未调用request方法,e==r==0
                // 2. 调用了request方法,则执行上面的分发代码,直到e==r
                if (e == r) {
                    if (isCancelled()) {
                        q.clear();
                        return;
                    }

                    boolean d = done;

                    boolean empty = q.isEmpty();

                    if (d && empty) {
                        Throwable ex = error;
                        if (ex != null) {
                            error(ex);
                        } else {
                            complete();
                        }
                        return;
                    }
                }

                if (e != 0) {
                    BackpressureHelper.produced(this, e);
                }

                // 未调用request方法,missed==0
                missed = wip.addAndGet(-missed);
                if (missed == 0) {
                    break;
                }
            }
        }
    }


BaseEmitter

由上面的分析,我们知道BufferAsyncEmitter继承BufferAsyncEmitter。

在示例中,我们说明了只有在Subscriber.onSubscribe方法中调用Subscription的request方法,事件才能发送。

示例代码:


 val subsrciber = object : Subscriber<String> {
        //由订阅时的代码分析可知, s此时实际上为BufferAsyncEmitter示例
        override fun onSubscribe(s: Subscription) {
            println("onSubscribe")
            // 不调用方法,无法发送流。
            s.request(Long.MAX_VALUE)
        }
}

BaseEmitter


abstract static class BaseEmitter<T>
    extends AtomicLong
    implements FlowableEmitter<T>, Subscription {

       BaseEmitter(Subscriber<? super T> actual) {
            this.actual = actual;
            this.serial = new SequentialDisposable();
        }

        @Override
        public void onComplete() {
            complete();
        }

        protected void complete() {
            if (isCancelled()) {
                return;
            }
            try {
                actual.onComplete();
            } finally {
                serial.dispose();
            }
        }

        @Override
        public final void request(long n) {
            if (SubscriptionHelper.validate(n)) {
                // 此处设置了AtomicLong为n
                BackpressureHelper.add(this, n);
                onRequested();
            }
        }


        // 省略......
}


订阅的核心是FlowableCreate和BaseEmitter这两个类,实现上还是比较清晰明了的。

3. 总结

本章只是简单的分析了RxJava2.0的订阅源码,RxJava的使用和实现远比此复杂,在此抛砖引玉,希望大家能活用、善用RxJava来提高工作效率,早日解放自己。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容