RxJava(2.0)-订阅源码分析

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

1. 使用实例

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

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

    // 2.创建观察者
    val subscriber = object : Subscriber {
        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 {

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

FlowableOnSubscribe

public interface FlowableOnSubscribe {

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

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

FlowableEmitter

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

public interface FlowableEmitter extends Emitter {

    /**
     * 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.
     * 

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)}. *

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 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. *

* 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 {

    /**
     * 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  Flowable create(FlowableOnSubscribe source, BackpressureStrategy mode) {
        ObjectHelper.requireNonNull(source, "source is null");
        ObjectHelper.requireNonNull(mode, "mode is null");
        return RxJavaPlugins.onAssembly(new FlowableCreate(source, mode));
    }

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

RxJavaPlugins.onAssembly

   public static  Flowable onAssembly(@NonNull Flowable source) {
        Function f = onFlowableAssembly;
        if (f != null) {
            return apply(f, source);
        }
        return source;
    }

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

FlowableCreate-实际创建的对象

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

    final FlowableOnSubscribe source;

    final BackpressureStrategy backpressure;

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

    @Override
    public void subscribeActual(Subscriber t) {
        BaseEmitter emitter;

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

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

2.2 创建观察者

    // 定义观察者
    val subscriber = object : Subscriber {
        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 {
    /**
     * Invoked after calling {@link Publisher#subscribe(Subscriber)}.
     * 

* No data will start flowing until {@link Subscription#request(long)} is invoked. *

* It is the responsibility of this {@link Subscriber} instance to call {@link Subscription#request(long)} whenever more data is wanted. *

* 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. *

* 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. *

* 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 s)



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


FlowableSubscriber


public interface FlowableSubscriber extends Subscriber {

    /**
     * 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 s)

public final void subscribe(FlowableSubscriber s) {
        ObjectHelper.requireNonNull(s, "s is null");
        try {
            // 附加操作
            Subscriber 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 s)

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

FlowableCreate.subscribeActual

public final class FlowableCreate extends Flowable {

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

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


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

    @Override
    public void subscribeActual(Subscriber t) {
        BaseEmitter emitter;

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


        private static final long serialVersionUID = 2427151001689639875L;

        final SpscLinkedArrayQueue queue;

        Throwable error;
        volatile boolean done;

        final AtomicInteger wip;

        // 1. actual实际的订阅者。
        // 2. capacityHint默认值为128。
        BufferAsyncEmitter(Subscriber actual, int capacityHint) {
            super(actual);
            this.queue = new SpscLinkedArrayQueue(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 a = actual;
            final SpscLinkedArrayQueue 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 {
        //由订阅时的代码分析可知, s此时实际上为BufferAsyncEmitter示例
        override fun onSubscribe(s: Subscription) {
            println("onSubscribe")
            // 不调用方法,无法发送流。
            s.request(Long.MAX_VALUE)
        }
}

BaseEmitter


abstract static class BaseEmitter
    extends AtomicLong
    implements FlowableEmitter, Subscription {

       BaseEmitter(Subscriber 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来提高工作效率,早日解放自己。

你可能感兴趣的:(RxJava(2.0)-订阅源码分析)