【源码分析】RxJava 1.2.2 实现简单事件流的原理

目前RxJava已经被广泛用于Android开发中,GitHub地址在这,官方文档说2018.03.31停止维护1.x 版本,本篇文章基于RxJava 1.2.2

关于RxJava的介绍文章推荐看扔物线给 Android 开发者的 RxJava 详解,这篇文章讲解了很多使用方法、结论和部分原理,虽然是两年前的文章,但现在看还是有不少的收获。

常用的类和接口

在正式开始分析之前,我们先来回顾一下RxJava中常用的一些类和接口,以利于后面的分析。

被观察者-类Observable,RxJava中核心的类,事件的生产者,它的大量操作符可以将一个Observable转换为另一个Observable。它有一个成员变量onSubscribe

public class Observable<T> {

    final OnSubscribe<T> onSubscribe;

    public interface OnSubscribe<T> extends Action1<Subscriber<? super T>> {
        // cover for generics insanity
    }
}

观察者-接口Observer,事件的消费者。

public interface Observer<T> {

    void onCompleted();

    void onError(Throwable e);

    void onNext(T t);
}

订阅-接口Subscription,被观察者和观察者形成订阅关系后,就有返回一个订阅,便于取消订阅。

public interface Subscription {

    void unsubscribe();

    boolean isUnsubscribed();
}

订阅者-抽象类Subscriber,实现了接口Observer和Subscription ,所以它可以接收事件,也可以取消订阅。事实上,在订阅过程中,Observer 也总会先被转换成一个 Subscriber 再使用。

public abstract class Subscriber<T> implements Observer<T>, Subscription {
    public void onStart() {
        // do nothing by default
    }
}

接口Function、Action系列,这些接口都有一个call()方法,接口名中的数字代表call()方法中的参数个数,区别在于Function系列的方法有返回值,而Action系列的方法没有返回值。

public interface Function {

}

public interface Func1<T, R> extends Function {
    R call(T t);
}

public interface Action extends Function {

}

public interface Action1<T> extends Action {
    void call(T t);
}

简单的事件流

下面的例子可以说是最简单的使用示例,创建一个被观察者,然后和观察者形成订阅关系。订阅后,被观察者调用3次onNext()方法,然后结束。本篇文章就从这段简单的代码入手,探究RxJava背后的原理。

Observable
        .create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("消息1");
                subscriber.onNext("消息2");
                subscriber.onNext("消息3");
                subscriber.onCompleted();
            }
        })
        .subscribe(new Subscriber<String>() {
            @Override
            public void onCompleted() {
                System.out.println("任务结束");
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("任务出错");
            }

            @Override
            public void onNext(String s) {
                System.out.println(s);
            }
        });

create()

public static <T> Observable<T> create(OnSubscribe<T> f) {
    return new Observable<T>(RxJavaHooks.onCreate(f));
}

protected Observable(OnSubscribe<T> f) {
    this.onSubscribe = f;
}

第2行有一个RxJavaHooks,之后我们会看到在RxJavahook频繁地出现,它的返回值类型和入参类型都一样。为简化分析,抓住重点,本篇文章不会对hook相关部分深入探究。

第5行将对成员变量onSubscribe赋值。

很明显,create()方法的作用就是将传入的onSubscribe赋值给成员变量onSubscribe

subscribe()

public final Subscription subscribe(Subscriber<? super T> subscriber) {
    return Observable.subscribe(subscriber, this);
}

static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
 // validate and proceed
    if (subscriber == null) {
        throw new IllegalArgumentException("subscriber can not be null");
    }
    if (observable.onSubscribe == null) {
        throw new IllegalStateException("onSubscribe function can not be null.");
        /*
         * the subscribe function can also be overridden but generally that's not the appropriate approach
         * so I won't mention that in the exception
         */
    }

    // new Subscriber so onStart it
    subscriber.onStart();

    /*
     * See https://github.com/ReactiveX/RxJava/issues/216 for discussion on "Guideline 6.4: Protect calls
     * to user code from within an Observer"
     */
    // if not already wrapped
    if (!(subscriber instanceof SafeSubscriber)) {
        // assign to `observer` so we return the protected version
        subscriber = new SafeSubscriber<T>(subscriber);
    }

    // The code below is exactly the same an unsafeSubscribe but not used because it would
    // add a significant depth to already huge call stacks.
    try {
        // allow the hook to intercept and/or decorate
        RxJavaHooks.onObservableStart(observable, observable.onSubscribe).call(subscriber);
        return RxJavaHooks.onObservableReturn(subscriber);
    } catch (Throwable e) {
        // special handling for certain Throwable/Error/Exception types
        Exceptions.throwIfFatal(e);
        // in case the subscriber can't listen to exceptions anymore
        if (subscriber.isUnsubscribed()) {
            RxJavaHooks.onError(RxJavaHooks.onObservableError(e));
        } else {
            // if an unhandled error occurs executing the onSubscribe we will propagate it
            try {
                subscriber.onError(RxJavaHooks.onObservableError(e));
            } catch (Throwable e2) {
                Exceptions.throwIfFatal(e2);
                // if this happens it means the onError itself failed (perhaps an invalid function implementation)
                // so we are unable to propagate the error correctly and will just throw
                RuntimeException r = new OnErrorFailedException("Error occurred attempting to subscribe [" + e.getMessage() + "] and then again while trying to pass to onError.", e2);
                // TODO could the hook be the cause of the error in the on error handling.
                RxJavaHooks.onObservableError(r);
                // TODO why aren't we throwing the hook's return value.
                throw r; // NOPMD
            }
        }
        return Subscriptions.unsubscribed();
    }
}

第19行调用了subscriberonStart()方法,我们可以在这个方法里做一些准备工作。

第35行调用了onSubscribecall()方法,参数为Subscriber, 这个方法来自于它继承的接口Action1,而我们在call()方法中调用了观察者的onNext()onCompleted()方法,被观察者开始发送事件,由此实现了事件由被观察者向观察者的传递。

这里分析的Observable是由create()方法创建的,我们手动在call()方法中调用了观察者的onNext()onCompleted()方法。Observable也可以由just()from()方法创建,这些方法创建的被观察者会自动调用观察者的onNext()onCompleted()onError方法,我们只需要传入简单的参数就可以了,但本质上和用create()方法创建是一样的。

subscribe()的不同重载方法还接受Action1Observer形式的参数,但它们都会被转换为Subscriber,最终进入刚才分析的subscribe()方法中。

至此,一次简单的事件流就清楚了:

  1. 赋值给成员变量onSubscribe
  2. 调用subscribe()方法订阅,回调onSubscribecall()方法,传入Subscriber作为参数,于是在call()方法中可以调用Subscriber的相关方法发送事件。
  3. 注意:只有在订阅后才开始发送事件。

线程调度

Observable中有大量的操作符可以实现变换,一般用的最多的估计就是线程调度了。我们给之前的例子加上Android中常用的线程切换:

Observable
        .create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("消息1");
                subscriber.onNext("消息2");
                subscriber.onNext("消息3");
                subscriber.onCompleted();
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<String>() {
            @Override
            public void onCompleted() {
                System.out.println("任务结束");
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("任务出错");
            }

            @Override
            public void onNext(String s) {
                System.out.println(s);
            }
        });

注意:使用AndroidSchedulers.mainThread()需要导入RxAndroid

我们来分析这段代码中线程调度实现的原理,接下来涉及的源码比较多,我们从序号1开始对源码片段作标记。

subscribeOn()

//第1段代码
public final Observable<T> subscribeOn(Scheduler scheduler) {
     if (this instanceof ScalarSynchronousObservable) {
         return ((ScalarSynchronousObservable<T>)this).scalarScheduleOn(scheduler);
     }
     return create(new OperatorSubscribeOn<T>(this, scheduler));
 }

可以看到,调用subscribeOn()方法后返回了一个新的Observable

第3行的判断在此时为false,我们直接看第6行,这个OperatorSubscribeOn是新的ObservableOnSubscribe,跟进OperatorSubscribeOn一探究竟。

//第2段代码
//rx.internal.operators.OperatorSubscribeOn
public final class OperatorSubscribeOn<T> implements OnSubscribe<T> {

    final Scheduler scheduler;
    final Observable<T> source;

    public OperatorSubscribeOn(Observable<T> source, Scheduler scheduler) {
        this.scheduler = scheduler;
        this.source = source;
    }

    @Override
    public void call(final Subscriber<? super T> subscriber) {
        final Worker inner = scheduler.createWorker();
        subscriber.add(inner);

        inner.schedule(new Action0() {
            @Override
            public void call() {
                final Thread t = Thread.currentThread();

                Subscriber<T> s = new Subscriber<T>(subscriber) {
                    @Override
                    public void onNext(T t) {
                        subscriber.onNext(t);
                    }

                    @Override
                    public void onError(Throwable e) {
                        try {
                            subscriber.onError(e);
                        } finally {
                            inner.unsubscribe();
                        }
                    }

                    @Override
                    public void onCompleted() {
                        try {
                            subscriber.onCompleted();
                        } finally {
                            inner.unsubscribe();
                        }
                    }

                    @Override
                    public void setProducer(final Producer p) {
                        subscriber.setProducer(new Producer() {
                            @Override
                            public void request(final long n) {
                                if (t == Thread.currentThread()) {
                                    p.request(n);
                                } else {
                                    inner.schedule(new Action0() {
                                        @Override
                                        public void call() {
                                            p.request(n);
                                        }
                                    });
                                }
                            }
                        });
                    }
                };

                source.unsafeSubscribe(s);
            }
        });
    }
}

在构造方法中,第9行和第10行分别保存了传入的ObservableScheduler

OperatorSubscribeOn作为新的ObservableOnSubscribe,根据之前对subscribe()方法的分析,它的call()方法将在订阅后被回调。那我们就来看一下它的call方法:

第15行创建了Worker类型的变量inner,为保持主逻辑的清晰,暂时先不管Worker是什么,继续看主逻辑。

先透露一下,调用第18行的schedule()方法后,最终将进入第20行的call()方法。

第23行创建了一个Subscriber,第67行的source就是刚才构造方法中传入的Observable,即上游Observable,这里将刚才创建的Subscriber作为参数传入了它的unsafeSubscribe()方法,继续跟进:

//第3段代码
//rx.Observable
public final Subscription unsafeSubscribe(Subscriber<? super T> subscriber) {
    try {
        // new Subscriber so onStart it
        subscriber.onStart();
        // allow the hook to intercept and/or decorate
        RxJavaHooks.onObservableStart(this, onSubscribe).call(subscriber);
        return RxJavaHooks.onObservableReturn(subscriber);
    } catch (Throwable e) {
        // special handling for certain Throwable/Error/Exception types
        Exceptions.throwIfFatal(e);
        // if an unhandled error occurs executing the onSubscribe we will propagate it
        try {
            subscriber.onError(RxJavaHooks.onObservableError(e));
        } catch (Throwable e2) {
            Exceptions.throwIfFatal(e2);
            // if this happens it means the onError itself failed (perhaps an invalid function implementation)
            // so we are unable to propagate the error correctly and will just throw
            RuntimeException r = new OnErrorFailedException("Error occurred attempting to subscribe [" + e.getMessage() + "] and then again while trying to pass to onError.", e2);
            // TODO could the hook be the cause of the error in the on error handling.
            RxJavaHooks.onObservableError(r);
            // TODO why aren't we throwing the hook's return value.
            throw r; // NOPMD
        }
        return Subscriptions.unsubscribed();
    }
}

从方法名能猜出这也是一个订阅方法,第6行更是和之前分析的subscribe()方法进行了相同的操作,调用了上游ObservableonSubscribecall()方法。

回到第2段代码,第26、32、41行的代码分别调用了下游Subscriber的对应方法。

至此,我们可以明白subscribeOn()究竟做了什么:

  1. 该方法返回了一个新的Observable
  2. 新的Observable收到订阅回调后,回调上游ObservableonSubscribecall()方法。
  3. 新的Observable中的OnSubscribecall回调中新建的Subscriber接收到事件后,继续将事件传递给下游的Subscriber

那说好的子线程切换又在哪里呢?

我们再回过头看第2段代码的Worker类,它由Scheduler创建而来。我们这里使用的SchedulerSchedulers.io(),跟进看一下:

//第4段代码
//rx.schedulers.Schedulers 只拷贝了相关核心代码
public final class Schedulers {
    private final Scheduler ioScheduler;

    public static Scheduler io() {
        return RxJavaHooks.onIOScheduler(getInstance().ioScheduler);
    }

    private Schedulers() {
       @SuppressWarnings("deprecation")
       RxJavaSchedulersHook hook = RxJavaPlugins.getInstance().getSchedulersHook();

       Scheduler c = hook.getComputationScheduler();
       if (c != null) {
           computationScheduler = c;
       } else {
           computationScheduler = RxJavaSchedulersHook.createComputationScheduler();
       }

       Scheduler io = hook.getIOScheduler();
       if (io != null) {
           ioScheduler = io;
       } else {
           ioScheduler = RxJavaSchedulersHook.createIoScheduler();
       }

       Scheduler nt = hook.getNewThreadScheduler();
       if (nt != null) {
           newThreadScheduler = nt;
       } else {
           newThreadScheduler = RxJavaSchedulersHook.createNewThreadScheduler();
       }
   }
}

第25行表明了ioScheduler的出处:

//第5段代码
//rx.plugins.RxJavaSchedulersHook 只拷贝了相关核心代码
public class RxJavaSchedulersHook {
    public static Scheduler createIoScheduler() {
        return createIoScheduler(new RxThreadFactory("RxIoScheduler-"));
    }

    public static Scheduler createIoScheduler(ThreadFactory threadFactory) {
        if (threadFactory == null) {
            throw new NullPointerException("threadFactory == null");
        }
        return new CachedThreadScheduler(threadFactory);
    }
}

第5行的 “RxIoScheduler-“是子线程的前缀,如果调试日志中有输出这个信息,那就会看到这个前缀。

第12行使用这个ThreadFactory构建了一个CachedThreadScheduler,继续跟进:

//第6段代码
//rx.internal.schedulers.CachedThreadScheduler 只拷贝了相关核心代码 
public final class CachedThreadScheduler extends Scheduler implements SchedulerLifecycle {

    private static final long KEEP_ALIVE_TIME = 60;
    private static final TimeUnit KEEP_ALIVE_UNIT = TimeUnit.SECONDS;
    final AtomicReference<CachedWorkerPool> pool;

    public CachedThreadScheduler(ThreadFactory threadFactory) {
        this.threadFactory = threadFactory;
        this.pool = new AtomicReference<CachedWorkerPool>(NONE);
        start();
    }

    @Override
    public void start() {
        CachedWorkerPool update =
            new CachedWorkerPool(threadFactory, KEEP_ALIVE_TIME, KEEP_ALIVE_UNIT);
        if (!pool.compareAndSet(NONE, update)) {
            update.shutdown();
        }
    }

    @Override
    public Worker createWorker() {
        return new EventLoopWorker(pool.get());
    }

    static final class EventLoopWorker extends Scheduler.Worker implements Action0 {
        private final CompositeSubscription innerSubscription = new CompositeSubscription();
        private final CachedWorkerPool pool;
        private final ThreadWorker threadWorker;
        final AtomicBoolean once;

        EventLoopWorker(CachedWorkerPool pool) {
            this.pool = pool;
            this.once = new AtomicBoolean();
            this.threadWorker = pool.get();
        }

        @Override
        public void unsubscribe() {
            if (once.compareAndSet(false, true)) {
                // unsubscribe should be idempotent, so only do this once

                // Release the worker _after_ the previous action (if any) has completed
                threadWorker.schedule(this);
            }
            innerSubscription.unsubscribe();
        }

        @Override
        public void call() {
            pool.release(threadWorker);
        }

        @Override
        public boolean isUnsubscribed() {
            return innerSubscription.isUnsubscribed();
        }

        @Override
        public Subscription schedule(Action0 action) {
            return schedule(action, 0, null);
        }

        @Override
        public Subscription schedule(final Action0 action, long delayTime, TimeUnit unit) {
            if (innerSubscription.isUnsubscribed()) {
                // don't schedule, we are unsubscribed
                return Subscriptions.unsubscribed();
            }

            ScheduledAction s = threadWorker.scheduleActual(new Action0() {
                @Override
                public void call() {
                    if (isUnsubscribed()) {
                        return;
                    }
                    action.call();
                }
            }, delayTime, unit);
            innerSubscription.add(s);
            s.addParent(innerSubscription);
            return s;
        }
    }

    static final class CachedWorkerPool {
        private final ThreadFactory threadFactory;
        private final long keepAliveTime;

        CachedWorkerPool(final ThreadFactory threadFactory, long keepAliveTime, TimeUnit unit) {
            this.threadFactory = threadFactory;
            this.keepAliveTime = unit != null ? unit.toNanos(keepAliveTime) : 0L;
            ...
            ...
        }
        ThreadWorker get() {
            if (allWorkers.isUnsubscribed()) {
                return SHUTDOWN_THREADWORKER;
            }
            while (!expiringWorkerQueue.isEmpty()) {
                ThreadWorker threadWorker = expiringWorkerQueue.poll();
                if (threadWorker != null) {
                    return threadWorker;
                }
            }

            // No cached worker found, so create a new one.
            ThreadWorker w = new ThreadWorker(threadFactory);
            allWorkers.add(w);
            return w;
        }
    }

    static final class ThreadWorker extends NewThreadWorker {
        private long expirationTime;

        ThreadWorker(ThreadFactory threadFactory) {
            super(threadFactory);
            this.expirationTime = 0L;
        }

        public long getExpirationTime() {
            return expirationTime;
        }

        public void setExpirationTime(long expirationTime) {
            this.expirationTime = expirationTime;
        }
    }

}

第9、10行分别给两个成员变量赋值。

别忘了第2段代码中的Worker是由SchedulercreateWorker()方法创建的,所以看一下第25行的createWorker()方法,pool.get()获取到的是pool指定的泛型CachedWorkerPool,将它传入EventLoopWorker的构造方法,在第38行调用了get()方法跳转到第99行,之后在第111行用刚才的threadFactory构造了ThreadWorker,于是在第121行进入父类NewThreadWorker的构造方法,该父类如下:

//第7段代码
//rx.internal.schedulers.NewThreadWorker 只拷贝了相关核心代码
public class NewThreadWorker extends Scheduler.Worker implements Subscription {
    private final ScheduledExecutorService executor;

    public NewThreadWorker(ThreadFactory threadFactory) {
        ScheduledExecutorService exec = Executors.newScheduledThreadPool(1, threadFactory);
        // Java 7+: cancelled future tasks can be removed from the executor thus avoiding memory leak
        boolean cancelSupported = tryEnableCancelPolicy(exec);
        if (!cancelSupported && exec instanceof ScheduledThreadPoolExecutor) {
            registerExecutor((ScheduledThreadPoolExecutor)exec);
        }
        executor = exec;
    }

    public ScheduledAction scheduleActual(final Action0 action, long delayTime, TimeUnit unit) {
        Action0 decoratedAction = RxJavaHooks.onScheduledAction(action);
        ScheduledAction run = new ScheduledAction(decoratedAction);
        Future<?> f;
        if (delayTime <= 0) {
            f = executor.submit(run);
        } else {
            f = executor.schedule(run, delayTime, unit);
        }
        run.add(f);

        return run;
    }
}

第7行使用Executors创建了一个线程池,传入了两个参数:核心线程数1、之前分析的带有前缀“RxIoScheduler-“的ThreadFactory。最大线程数为Integer.MAX_VALUE,非核心线程保留10ms。

第2段代码的Worker会调用schedule方法,所以再回到第6段代码的68行,之后在第74行调用了ThreadWorkerscheduleActual()方法,于是跳转到第7段代码的第16行。第17行对action进行了包装,第18行将包装后的action转换成ScheduledAction对象,这是一个Runnable对象,所以第21行可以将它作为executor.submit()方法的参数,这个executor就是刚才创建的线程池。

之后线程池将会新开线程,并调用ScheduledActionrun()方法,继续跟进:

//第8段代码
//rx.internal.schedulers.ScheduledAction 只拷贝了相关核心代码
public final class ScheduledAction extends AtomicReference<Thread> implements Runnable, Subscription {
    final SubscriptionList cancel;
    final Action0 action;

    public ScheduledAction(Action0 action) {
        this.action = action;
        this.cancel = new SubscriptionList();
    }

    @Override
    public void run() {
        try {
            lazySet(Thread.currentThread());
            action.call();
        } catch (OnErrorNotImplementedException e) {
            signalError(new IllegalStateException("Exception thrown on Scheduler.Worker thread. Add `onError` handling.", e));
        } catch (Throwable e) {
            signalError(new IllegalStateException("Fatal Exception thrown on Scheduler.Worker thread.", e));
        } finally {
            unsubscribe();
        }
    }

}

第16行的action就是刚才包装后的decoratedAction,所以跳转到第6段代码的第76行,之后在第80行又回调call()方法,跳转到第2段代码的第20行,接着就是之前分析过的 “回调上游Observable的onSubscribe的call()方法”。

至此,第2段代码就已经打通了,子线程也已经开始运行。

我们对subscribeOn()的总结再加以完善:

  1. 该方法返回了一个新的Observable
  2. 新的Observable收到订阅回调后, 创建了一个核心线程数为1,最大线程数为Integer.MAX_VALUE的线程池,新线程名的前缀为 “RxIoScheduler-“,之后的代码将运行在新线程中,直到遇到线程切换。
  3. 通过层层回调,最终回调了上游ObservableonSubscribecall()方法。
  4. 新的Observable中的OnSubscribecall回调中新建的Subscriber接收到事件后,继续将事件传递给下游的Subscriber
  5. 该方法改变的是上游回调call()方法执行时所处的线程,当使用多个 subscribeOn() 时,只有第一个subscribeOn() 决定事件发送时的线程。

observeOn()

现在我们看一下observeOn(AndroidSchedulers.mainThread())这行代码实现的原理:

//第9段代码
public final Observable<T> observeOn(Scheduler scheduler) {
    return observeOn(scheduler, RxRingBuffer.SIZE);
}

public final Observable<T> observeOn(Scheduler scheduler, int bufferSize) {
    return observeOn(scheduler, false, bufferSize);
}

public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
        if (this instanceof ScalarSynchronousObservable) {
            return ((ScalarSynchronousObservable<T>)this).scalarScheduleOn(scheduler);
        }
        return lift(new OperatorObserveOn<T>(scheduler, delayError, bufferSize));
}

public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
        return create(new OnSubscribeLift<T, R>(onSubscribe, operator));
}

经过两个方法的调用,在第14行出现了新的对象OperatorObserveOn,先不管它,继续看主逻辑。

第18行又是我们熟悉的create()方法,不用多说,它的参数是个OnSubscribe接口对象,跟进OnSubscribeLift

//第10段代码
public final class OnSubscribeLift<T, R> implements OnSubscribe<R> {

    final OnSubscribe<T> parent;

    final Operator<? extends R, ? super T> operator;

    public OnSubscribeLift(OnSubscribe<T> parent, Operator<? extends R, ? super T> operator) {
        this.parent = parent;
        this.operator = operator;
    }

    @Override
    public void call(Subscriber<? super R> o) {
        try {
            Subscriber<? super T> st = RxJavaHooks.onObservableLift(operator).call(o);
            try {
                st.onStart();
                parent.call(st);
            } catch (Throwable e) {
                Exceptions.throwIfFatal(e);
                st.onError(e);
            }
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            o.onError(e);
        }
    }
}

这个类代码不多,比较简单。第16行新建了一个Subscriber对象,紧接着又是熟悉的操作:调用这个新Subscriber对象的onStart()方法、回调上游OnSubscribecall()方法。

很明显,这里收到订阅回调后没有发生线程切换,也没有其他多余的操作。

那这个新的Subscriber对象接收到事件后,又发生了什么呢?

根据第16行,我们要看第9段代码第14行OperatorObserveOncall()方法来了解这个新的Subscriber对象了:

//第11段代码
//rx.internal.operators.OperatorObserveOn 只拷贝了相关核心代码
public final class OperatorObserveOn<T> implements Operator<T, T> {

    public OperatorObserveOn(Scheduler scheduler, boolean delayError, int bufferSize) {
        this.scheduler = scheduler;
        this.delayError = delayError;
        this.bufferSize = (bufferSize > 0) ? bufferSize : RxRingBuffer.SIZE;
    }

    @Override
    public Subscriber<? super T> call(Subscriber<? super T> child) {
        if (scheduler instanceof ImmediateScheduler) {
            // avoid overhead, execute directly
            return child;
        } else if (scheduler instanceof TrampolineScheduler) {
            // avoid overhead, execute directly
            return child;
        } else {
            ObserveOnSubscriber<T> parent = new ObserveOnSubscriber<T>(scheduler, child, delayError, bufferSize);
            parent.init();
            return parent;
        }
    }

    static final class ObserveOnSubscriber<T> extends Subscriber<T> implements Action0 {
        public ObserveOnSubscriber(Scheduler scheduler, Subscriber<? super T> child, boolean delayError, int bufferSize) {
            this.child = child;
            this.recursiveScheduler = scheduler.createWorker();
            this.delayError = delayError;
            ...
            ...
        }

        @Override
        public void onNext(final T t) {
            if (isUnsubscribed() || finished) {
                return;
            }
            if (!queue.offer(NotificationLite.next(t))) {
                onError(new MissingBackpressureException());
                return;
            }
            schedule();
        }

        @Override
        public void onCompleted() {
            if (isUnsubscribed() || finished) {
                return;
            }
            finished = true;
            schedule();
        }

        @Override
        public void onError(final Throwable e) {
            if (isUnsubscribed() || finished) {
                RxJavaHooks.onError(e);
                return;
            }
            error = e;
            finished = true;
            schedule();
        }

        protected void schedule() {
            if (counter.getAndIncrement() == 0) {
                recursiveScheduler.schedule(this);
            }
        }
    }
}

进入第12行的call()方法,因为我们使用的是AndroidSchedulers.mainThread(),所以就直接到了第20行。这里将ObserveOnSubscriber作为Subscriber返回,所以再看这个对象的onNext()等方法就知道如何处理事件了。

第40行将当前接收到的事件保存进了队列queue,先记住这点,后面就会用到了。

第44、53、64行都调用了schedule()这个方法。注意:onCompleted()onError方法中都将标志位finished设为了true

第69行调用了recursiveSchedulerschedule()方法,recursiveScheduler是在第20行跳到29行赋值的,我们需要找到AndroidSchedulers.mainThread()createWorker()方法,先找到AndroidSchedulers.mainThread()

//第12段代码
//rx.android.schedulers.AndroidSchedulers 只拷贝了相关核心代码
public final class AndroidSchedulers {
    private final Scheduler mainThreadScheduler;

    private AndroidSchedulers() {
        RxAndroidSchedulersHook hook = RxAndroidPlugins.getInstance().getSchedulersHook();

        Scheduler main = hook.getMainThreadScheduler();
        if (main != null) {
            mainThreadScheduler = main;
        } else {
            mainThreadScheduler = new LooperScheduler(Looper.getMainLooper());
        }
    }
}

第13行用主线程的Looper构建了LooperScheduler,继续跟进:

//第13段代码
//rx.android.schedulers.Scheduler 
class LooperScheduler extends Scheduler {
    private final Handler handler;

    LooperScheduler(Looper looper) {
        handler = new Handler(looper);
    }

    @Override
    public Worker createWorker() {
        return new HandlerWorker(handler);
    }

    static class HandlerWorker extends Worker {

        @Override
        public Subscription schedule(final Action0 action) {
            return schedule(action, 0, TimeUnit.MILLISECONDS);
        }

        @Override
        public Subscription schedule(Action0 action, long delayTime, TimeUnit unit) {
            if (unsubscribed) {
                return Subscriptions.unsubscribed();
            }

            action = hook.onSchedule(action);

            ScheduledAction scheduledAction = new ScheduledAction(action, handler);

            Message message = Message.obtain(handler, scheduledAction);
            message.obj = this; // Used as token for unsubscription operation.

            handler.sendMessageDelayed(message, unit.toMillis(delayTime));

            if (unsubscribed) {
                handler.removeCallbacks(scheduledAction);
                return Subscriptions.unsubscribed();
            }

            return scheduledAction;
        }
    }

    static final class ScheduledAction implements Runnable, Subscription {
        ScheduledAction(Action0 action, Handler handler) {
            this.action = action;
            this.handler = handler;
        }

         @Override
         public void run() {
            try {
                action.call();
            } catch (Throwable e) {
              ...
            }
        }
    }
}

第12行又用主线程的Looper构建了HandlerWorker,所以只要看HandlerWorkerschedule()方法就行了。

第35行向主线程的消息队列发送了一条消息,这条消息将被主线程的Looper取出,到时候第30行scheduledAction的回调run()方法就会在主线程执行了,这就实现了切换回主线程的目的

再看第53行,run()方法里又回调了actioncall()方法,即第11段代码第26行类ObserveOnSubscriber所实现的方法,如下:

@Override
public void call() {
    long missed = 1L;
    long currentEmission = emitted;
    final Queue<Object> q = this.queue;
    final Subscriber<? super T> localChild = this.child;
    for (;;) {
        long requestAmount = requested.get();

        while (requestAmount != currentEmission) {
            boolean done = finished;
            Object v = q.poll();
            boolean empty = v == null;

            if (checkTerminated(done, empty, localChild, q)) {
                return;
            }

            if (empty) {
                break;
            }

            localChild.onNext(NotificationLite.<T>getValue(v));

            currentEmission++;
            if (currentEmission == limit) {
                requestAmount = BackpressureUtils.produced(requested, currentEmission);
                request(currentEmission);
                currentEmission = 0L;
            }
        }

        if (requestAmount == currentEmission) {
            if (checkTerminated(finished, q.isEmpty(), localChild, q)) {
                return;
            }
        }

        emitted = currentEmission;
        missed = counter.addAndGet(-missed);
        if (missed == 0L) {
            break;
        }
    }
}

第6行的localChild就是下游Subscriber,这从第11代码中不难发现。

第12行取出了之前保存在队列queue中的事件,第23行调用了下游SubscriberonNext()方法,事件继续向下传递,而这一切都发生在主线程中。

至此,对observeOn()方法可以有如下总结:

  1. 该方法返回了一个新的Observable
  2. 新的Observable收到订阅回调后,回调了上游ObservableonSubscribecall()方法。
  3. 新的Observable中的OnSubscribecall回调中新建的Subscriber接收到事件后,将事件包装后发送到主线程的消息队列。
  4. 在主线程中,事件继续向下游Subscriber传递。
  5. 该方法改变的是下游订阅者方法执行时所处的线程,可以通过多次调用observeOn()方法,实现下游订阅者在多个线程间切换执行。

线程调度总结

以上对两种线程调度操作符都做了详细的分析和总结,切换线程时一个利用线程池,一个利用主线程Looper消息机制。

再配合下面这幅流程图食用,消化更佳~

这幅图来自于扔物线给 Android 开发者的 RxJava 详解,因为这幅图总结地很好,和本文分析的结论也是完全一致,所以就直接拿来用了。

这里写图片描述

相信理解完本文内容,大家对RxJava 1.x应该有了较好的认识,当然它的其他实现原理也很值得我们再深入研究。

猜你喜欢

转载自blog.csdn.net/recordGrowth/article/details/79758647
今日推荐