我的RxJava源码解读笔记

RxJava是一个用于处理异步任务的库,本篇文章我将把我在学习RxJava源码时的分析思路记载下来,一方面用来加强记忆,另一方面可以供大家参考。

首先梳理一下RxJav主要功能的工作流程,然后通过源码了解其工作原理,最后介绍一下RxJava的实战用法

(我在分析时用的是1.1版本,在最新的版本中部分代码可能会有变化~)

使用流程简述

首先,RxJava这个东西相信大家一定不会陌生,我在学习过程中看到的这两篇文章:

RxJava系列

给Android开发者的RxJava详解

上述两篇文章已经很透彻的将RxJava介绍了个遍,推荐大家看一下,很有帮助的。所以在这里我就简单的说一下他的工作流程。

RxJava采取的是观察者模式,使用时要先分别创建一个观察者Observer或Subscriber处理接收到数据后要做的处理(onNext,onError,onCompleted),一个被观察者Observable用来发送要处理的数据,最后由被观察者订阅观察者(subscribe),这时要发送的数据就会由被观察发出,然后观察者做出相应处理。用代码来简单描述为:

//创建被观察者
Observable observable = Observable.create(new Observable.OnSubscribe<String>() {

            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("hello world");
            }
});

//创建观察者
        Subscriber<String> subscriber = new Subscriber<String>() {
            @Override
            public void onCompleted() {
                //completed
            }

            @Override
            public void onError(Throwable e) {
                //error
            }

            @Override
            public void onNext(String s) {
                //do it
            }
};


//订阅事件
observable.subscribe(subscriber);

套用最近比较火的一首歌《PPAP》的歌词,“I have a Observer,I have a Observable,en——Observable subscribe Observer!”

这里有个问题,为什么是被观察者订阅观察者而不观察者订阅被观察者呢?我认为应该是这样:被观察者,即发送数据方,他的数据可以发送给多个观察者,即可以有多个观察者观察他,因此他是占据主导权的,他想让哪个观察者看就订阅哪个观察者把数据发给他。

当然,观察者,被观察者及订阅的代码还有很多简单的书写方式,如直接使用just()等方法发送数据,不创建观察者而是在subscribe()方法中传递几个Action()方法等等,在这里我只是展示了最基本的一套用法用来比较清晰地梳理一下工作流程。除此之外,RxJava还可以切换线程,可以对数据进行变换,这些都是在订阅过程中完成的,代码如下:

observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map(new Func1<String,Integer>() {
                    @Override
                    public Integer call(String s) {
                        //do String --> Integer
                        return 0;
                    }
                })
                .filter(new Func1<Integer,Boolean>() {
                    @Override
                    public Boolean call(Integer integer) {
                        //return your boolean
                        return integer>10;
                    }
                })
                .subscribe(subscriber);

其中,在切换线程时,subscribeOn指定subscribe发生的线程,observeOn指定Subscriber的回调发生的线程,其他操作符如过滤、变换操作符可以自己琢磨一下。

以上,就是RxJava大体上的使用流程,接下来我将从源码角度看一下他的实际工作过程。


工作原理

1.创建Observable

首先看看Observable里面有哪些变量:

final OnSubscribe<T> onSubscribe;

别找了,就这一个,其他全是各种类方法,暂且不用管。

然后看看create的源码:

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

通过传入一个OnSubscribe对象,将其作为参数传入hook.onCreate()方法,将返回值作为参数构造一个Observable对象。这里的 hook 是一个static的RxJavaObservableExecutionHook对象,他的create()方法是这样的:

public <T> OnSubscribe<T> onCreate(OnSubscribe<T> f) {
        return f;
}

他接受一个OnSubscribe对象,然后就将他返回。好像没啥卵用?好吧,不管怎么说,hook.create(f) 可以等价的看作是 f 本身,那么 Observable 的构造器接受的就是一个OnSubscribe对象了,看看他的构造器:

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

恩,这里将传入的OnSubscribe对象赋给了自己的onSubscribe。

分析完了,创建Observable就是给他一个OnSubscribe对象,把他传入构造器创建一个Observable对象。那么问题莱恩,OnSubscribe是什么?

2.OnSubscribe是什么?

看看OnSubscribe源码:

/**
     * Invoked when Observable.subscribe is called.
     */
public interface OnSubscribe<T> extends Action1<Subscriber<? super T>>{
        // cover for generics insanity
}

原来是继承自 Action1 的一个接口,注释说他在subscribe被调用的时候唤醒,没搞懂什么意思,张磊(BaronZhang) dalao说:“从纯设计模式的角度来理解,OnSubscribe.call()可以看做是观察者模式中被观察者用来通知观察者的notifyObservers()方法”,通过google我还知道了这么几种说法“OnSubscribe负责RxJava中事务的执行”。综合一下,OnSubscribe应该就是所谓的“事务”,他的call方法负责发起事务,即notifyObservers()。结合前面分析的使用过程,在创建Observable时传入的OnSubscribe中实现了call方法并且执行了subscriber的一些方法,嗯……这样分析还是有点道理的。

3.创建观察者Observer/Subscriber

首先看Observer的定义:

public interface Observer<T> {
    void onCompleted();
    void onError(Throwable e);
    void onNext(T t);
}

只是一个简单的接口,再看看Subscriber:

public abstract class Subscriber<T> implements Observer<T>,Subscription{

Subscriber是一个实现了Observer接口的抽象类,并且还扩充了许多方法。既然如此,那我们在使用RxJava时就应当尽量用Subscriber代替Observer了。

看看他有哪些属性:

// represents requested not set yet
    private static final Long NOT_SET = Long.MIN_VALUE;

    private final SubscriptionList subscriptions;
    private final Subscriber<?> subscriber;
    /* protected by `this` */
    private Producer producer;
    /* protected by `this` */
    private long requested = NOT_SET; // default to not set

他持有一个自己的引用,一个SubscriptionList引用。分析一下,创建一个观察者Subscriber,就必须要实现来自Observer接口的三个方法:onNext(), onError(), onCompleted()。

4.订阅subscribe

创建好观察者和被观察者之后,就可以进行订阅了:

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

在subscribe方法中又调用了Observer的一个私有方法:

private static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
     // validate and proceed
        if (subscriber == null) {
            throw new IllegalArgumentException("observer 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 Guideline 6.4: Protect calls to user code from within an operator · Issue #216 · ReactiveX/RxJava 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
            hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);
            return hook.onSubscribeReturn(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(hook.onSubscribeError(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 RuntimeException("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.
                hook.onSubscribeError(r);
                // TODO why aren't we throwing the hook's return value.
                throw r;
            }
            return Subscriptions.unsubscribed();
        }
}

精简一下这个方法,逐步分析。首先,对传入的subscriber对象和observable.onSubscribe方法判空,然后执行了sunscriber的start()方法,之后对subscriber做了安全性封装:

if (!(subscriber instanceof SafeSubscriber)) {
            // assign to `observer` so we return the protected version
            subscriber = new SafeSubscriber<T>(subscriber);
}

所有检测完毕,开始执行下列方法:

hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);
            return hook.onSubscribeReturn(subscriber);

又看到那个熟悉的hook了,看看他的onSubscribeStart方法是怎样实现的:

public <T> OnSubscribe<T> onSubscribeStart(Observable<? extends T> observableInstance, final OnSubscribe<T> onSubscribe) {
        // pass-thru by default
        return onSubscribe;
}

传给了observer对象和他的onSubscribe对象,结果直接把后者返回了……有趣的设计,返回之后又继续调用了onSubscribe对象的call()方法,并传入了subscriber对象。

5.Subscription

在分析订阅部分代码时,我发现了subscribe()方法完成后,执行了Subscriptions的unsubscribed()方法并返回。这个Subscription是什么呢?

/**
 * Subscription returns from {@link Observable#subscribe(Subscriber)} to allow unsubscribing.
 * <p>
 * See the utilities in {@link Subscriptions} and the implementations in the {@code rx.subscriptions} package.
 * <p>
 * This interface is the RxJava equivalent of {@code IDisposable} in Microsoft's Rx implementation.
 */
public interface Subscription {

    /**
     * Stops the receipt of notifications on the {@link Subscriber} that was registered when this Subscription
     * was received.
     * <p>
     * This allows unregistering an {@link Subscriber} before it has finished receiving all events (i.e. before
     * onCompleted is called).
     */
    void unsubscribe();

    /**
     * Indicates whether this {@code Subscription} is currently unsubscribed.
     *
     * @return {@code true} if this {@code Subscription} is currently unsubscribed, {@code false} otherwise
     */
    boolean isUnsubscribed();

}

一直说观察者模式中要订阅,要订阅,怎么取消订阅呢?原来就在这里。我的理解,Subscription可以理解为一件订阅事务,他有一个取消订阅和检测是否取消的方法。每一个订阅事件,最后是可以返回这样一个subscription对象的。我们完全可以把这个对象收集起来,在需要的时候将他取消订阅。例如像下面这样:

private CompositeSubscription subscriptions = new CompositeSubscription();
//创建一个异步任务
subscriptions.add(subscription);//将subscription加入合集中
subscriptions.unsubscribe();//取消订阅

6.变换:map()

RxJava的操作符很多,我这里只选一个最基础的map来看看,首先看map代码如下:

//这段代码是我在1.1版本中分析的,在1.2.2中已经更改了实现方式,多谢评论区提醒~
public final <R> Observable<R> map(Func1<? super T, ? extends R> func){
        return lift(new OperatorMap<T, R>(func));
}

在内部调用了lift()方法,并将结果返回了。可以看到,变换的过程中,将包含T在内的T的基类变换为了包含R在内的R的子类,所以这里重点要看两个地方,一是lift()如何实现,二是OperatorMap是什么。先看看lift()方法的实现:

public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
        return new Observable<R>(new OnSubscribe<R>() {
            @Override
            public void call(Subscriber<? super R> o) {
                try {
                    Subscriber<? super T> st = hook.onLift(operator).call(o);
                    try {
                        // new Subscriber created and being subscribed with so 'onStart' it
                        st.onStart();
                        onSubscribe.call(st);
                    } catch (Throwable e) {
                        // localized capture of errors rather than it skipping all operators 
                        // and ending up in the try/catch of the subscribe method which then
                        // prevents onErrorResumeNext and other similar approaches to error handling
                        Exceptions.throwIfFatal(e);
                        st.onError(e);
                    }
                } catch (Throwable e) {
                    Exceptions.throwIfFatal(e);
                    // if the lift function failed all we can do is pass the error to the final Subscriber
                    // as we don't have the operator available to us
                    o.onError(e);
                }
            }
        });
    }

可以看到,在lift内部用类型R又重新创建了一个Observable。注意观察,这里的代码和调用subscribe()时很像,但又不同。对比一下发现,在subscribe()时,是由Observable自己的OnSubscribe调用了call()方法,并将自己的subscriber作为参数传入call()。但是在这里,通过一个新的OnSubscribe创建了一个新的Observable,在内部先创建了一个新的Subscriber,然后由旧的onSubscribe调用自己的call()方法,这里传入的又是新的Subscriber。新旧之间的关联就在于新的SUbscriber创建的过程:

Subscriber<? super T> st = hook.onLift(operator).call(o);

可以看到,创建新的Subscriber时用到了我们传入的operator,看看hook的lift()实现:

public <T, R> Operator<? extends R, ? super T> onLift(final Operator<? extends R, ? super T> lift) {
        return lift;
}

把传入的operator又原样返回了。那么前面的代码就可以简化为operator直接调用了call()方法。我们自己写的变换代码就是实现了这个operator的call()方法。

.map(new Func1<String,Integer>() {
                    @Override
                    public Integer call(String s) {
                        //do String --> Integer
                        return 0;
                    }
                })

看看前面的代码,我们传入的这个Func1,在内部会由他创建一个OperatorMap,然后将OperatorMap传入了lift(),这个OperatorMap就是我们刚才讲的operator的来源。

再来看看OperatorMap是什么:

public final class OperatorMap<T, R> implements Operator<R, T> {

    private final Func1<? super T, ? extends R> transformer;

    public OperatorMap(Func1<? super T, ? extends R> transformer) {
        this.transformer = transformer;
    }

    @Override
    public Subscriber<? super T> call(final Subscriber<? super R> o) {
        return new Subscriber<T>(o) {

            @Override
            public void onCompleted() {
                o.onCompleted();
            }

            @Override
            public void onError(Throwable e) {
                o.onError(e);
            }

            @Override
            public void onNext(T t) {
                try {
                    o.onNext(transformer.call(t));
                } catch (Throwable e) {
                    Exceptions.throwOrReport(e, this, t);
                }
            }

        };
    }

}

可以看到,当构造一个OperatorMap时,传入了一个func,在OperatorMap构造器中,是将其赋给了自己记得一个叫做transformer的属性,这个transformer是一个Func1对象,因此我们的实现变换的主要细节其实就在于这个Func1。

7.变换:compose()

除了最基础的mao进行变换外,我们常用的还有compose变换,看看他是怎么实现的:

public <R> Observable<R> compose(Transformer<? super T, ? extends R> transformer) {
        return ((Transformer<T, R>) transformer).call(this);
}

通过compose变换时,传入的是一个transfomer,最后调用的是他的call()方法。transfomer就是前面Map变换中用到的那个,综合来看,在RxJava中进行变换时,是通过创建新的Observable进行代理来实现的,而具体实现细节使用了transformer。

8.线程切换:subscrieOn()

subscribeOn()指定了subscribe()所发生的线程,看看他是怎样实现的:

public final Observable<T> subscribeOn(Scheduler scheduler) {
        if (this instanceof ScalarSynchronousObservable) {
            return ((ScalarSynchronousObservable<T>)this).scalarScheduleOn(scheduler);
        }
        return nest().lift(new OperatorSubscribeOn<T>(scheduler));
}

先调用了nest(),返回一个Observable对象,然后调用lift()进行变换,进行变换时传入的是一个由线程调度器scheduler构造的OperatorSubscribeOn对象。先看看nest中发生了什么:

public final Observable<Observable<T>> nest() {
        return just(this);
}

把自己传给了just()方法:

public final static <T> Observable<T> just(final T value) {
        return ScalarSynchronousObservable.create(value);
}

这个ScalarSynchronousObservable是继承自Observabel的,到头来还是调用create()创建了一个Observable对象。lift()方法前面已经分析过了,lift()中创建了一个新的Observable,这里不同的地方在于传入的是一个线程调度器scheduler而非OperatorMap,所以线程调度的具体实现应该就是由scheduler和OperatorSubscribeOn来决定的了。那么接下来就看看OperatorSubscribeOn是如何实现线程控制的。首先根据上面的分析,这里传入了一个scheduler对象给构造器,点进来看看他的实现,:

public class OperatorSubscribeOn<T> implements Operator<T, Observable<T>> {

    private final Scheduler scheduler;

    public OperatorSubscribeOn(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

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

            @Override
            public void onCompleted() {
                // ignore because this is a nested Observable and we expect only 1 Observable<T> emitted to onNext
            }

            @Override
            public void onError(Throwable e) {
                subscriber.onError(e);
            }

            @Override
            public void onNext(final Observable<T> o) {
                inner.schedule(new Action0() {

                    @Override
                    public void call() {
                        final Thread t = Thread.currentThread();
                        o.unsafeSubscribe(new Subscriber<T>(subscriber) {

                            @Override
                            public void onCompleted() {
                                subscriber.onCompleted();
                            }

                            @Override
                            public void onError(Throwable e) {
                                subscriber.onError(e);
                            }

                            @Override
                            public void onNext(T t) {
                                subscriber.onNext(t);
                            }

                            @Override
                            public void setProducer(final Producer producer) {
                                subscriber.setProducer(new Producer() {

                                    @Override
                                    public void request(final long n) {
                                        if (Thread.currentThread() == t) {
                                            // don't schedule if we're already on the thread (primarily for first setProducer call)
                                            // see unit test 'testSetProducerSynchronousRequest' for more context on this
                                            producer.request(n);
                                        } else {
                                            inner.schedule(new Action0() {

                                                @Override
                                                public void call() {
                                                    producer.request(n);
                                                }
                                            });
                                        }
                                    }

                                });
                            }

                        });
                    }
                });
            }

        };
    }
}

可以看到,在构造器中,传入的scheduler赋给了自己的scheduler,然后在call方法中,通过scheduler创建了一个worker对象,名叫inner,之后的所有操作都是由inner完成的。总结一下,就是传入的scheduler创建了一个worker对象,由这个对象进行了实际上的线程控制。所以线程控制的关键就在于这个scheduler。而scheduler就是我们在使用过程中传入的Schedulers.io()等,这里就拿Schedulers.io()看看。

public static Scheduler io() {
        return INSTANCE.ioScheduler;
}

再看看Schedulers类的构造器,可以知道INSTANCE.ioSchduler是在构造器中进行初始化的:

Scheduler io = RxJavaPlugins.getInstance().getSchedulersHook().getIOScheduler();
        if (io != null) {
            ioScheduler = io;
        } else {
            ioScheduler = new CachedThreadScheduler();
        }

再结合:

/**
     * Scheduler to return from {@link rx.schedulers.Schedulers#io()} or null if default should be used.
     *
     * This instance should be or behave like a stateless singleton;
     */
    public Scheduler getIOScheduler() {
        return null;
    }

可知,ioScheduler是由CacheThreadSchduler这个类创建的,这个类继承自Scheduler,那么也就是说抽象类Scheduler的createWorker()方法由子类CacheThreadSchduler实现了。那就来看看这个方法具体的实现:

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

可以看到,createWorker()方法返回了一个EventLoopWorker对象。而这个类是CacheThreadSchduler类的内部类。回忆一下,之前我们创建好worker之后,他是如何工作的?:

inner.schedule(new Action0() {...};

是有这个worker对象调用了schedule()方法,并且传入了一个Action0。那么就来看看worker的源头,EventLoopWorker,在schedule()时做了什么:

private static final class EventLoopWorker extends Scheduler.Worker {
        /* 省略部分代码*/
        @Override
        public Subscription schedule(Action0 action) {
            return schedule(action, 0, null);
        }

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

            ScheduledAction s = threadWorker.scheduleActual(action, delayTime, unit);
            innerSubscription.add(s);
            s.addParent(innerSubscription);
            return s;
        }
    }

可以看到,最终实际上是调用了thread.scheduleActual()方法,并将action传给了他,返回一个 ScheduledAction 对象。那么看看这个方法内部是如何实现的:

public ScheduledAction scheduleActual(final Action0 action, long delayTime, TimeUnit unit) {
        Action0 decoratedAction = schedulersHook.onSchedule(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;
    }

创建了一个ScheduledAction的对象,并将其返回,而ScheduledAction类是实现了Runnable接口的:

public final class ScheduledAction extends AtomicReference<Thread> implements Runnable, Subscription {

因此,具体対线程的操作就是在这里了。总结一下,SubscribeOn() 是通过 life() 变换来完成的,而在变换中实际上是通过 CachedThreadScheduler 类提供的 schedule() 方法,用Runnable来完成的线程控制。

9.线程切换:observeOn()

和 subscribeOn() 方法一样,observeOn() 方法实现原理也是通过 lift() 变换:

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

类似的,这里也是传入了一个Operator,不同的是这里传入的是通过scheduler创建的OperatorObserveOn对象。先来看看OperatorObserveOn的构造器:

public OperatorObserveOn(Scheduler scheduler) {
        this.scheduler = scheduler;
}

类似的,将传入的 scheduler 赋给了自己的 scheduler 属性。这个scheduler 在哪里用到了呢?首先是在回调方法 call() 中:

@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);
            parent.init();
            return parent;
        }
}

通过scheduler创建了一个 ObserveOnSubscriber 对象 parent ,并调用了 init() 方法。这个 ObserveOnSubscriber 类是一个内部类,他的构造器:

public ObserveOnSubscriber(Scheduler scheduler, Subscriber<? super T> child) {
            this.child = child;
            this.recursiveScheduler = scheduler.createWorker();
            if (UnsafeAccess.isUnsafeAvailable()) {
                queue = new SpscArrayQueue<Object>(RxRingBuffer.SIZE);
            } else {
                queue = new SynchronizedQueue<Object>(RxRingBuffer.SIZE);
            }
            this.scheduledUnsubscribe = new ScheduledUnsubscribe(recursiveScheduler);
}

在这里就调用了 scheduler 的 createWorker() 方法,并将返回结果赋给了自己的 recursiveScheduler ,然后由他创建了 ScheduledUnsubscribe 对象,将这个对象赋给了 scheduledUnsubscribe。好像有点乱,大概理一下,这里创建了一个 Subscriber 对象,在内部做了一些初始化的操作,而这个Subscriber 对象实际上就是 ObserveOnSubscriber 的对象。观察 ObserveOnSubscriber 类:

@Override
        public void onNext(final T t) {
            if (isUnsubscribed()) {
                return;
            }
            if (!queue.offer(on.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) {
                return;
            }
            error = e;
            // unsubscribe eagerly since time will pass before the scheduled onError results in an unsubscribe event
            unsubscribe();
            finished = true;
            // polling thread should skip any onNext still in the queue
            schedule();
        }

会发现,在这三个被调用的方法中都会调用 schedule() 方法,而 schedule() 方法的实现是这样的:

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

注意,这个 recursiveScheduler 就是前面创建的worker。所以控制线程切换的关键还是在于传入的 scheduler及他所创建的 worker 和worker的 schedule() 方法。传入的 scheduler 有很多种,就拿 AndroidSchedulers.mainThread() 来说:

public final class AndroidSchedulers {
    private AndroidSchedulers() {
        throw new AssertionError("No instances");
    }

    // See Unit testing support for AndroidSchedulers · Issue #238 · ReactiveX/RxAndroid
    // Initialization-on-demand holder idiom
    private static class MainThreadSchedulerHolder {
        static final Scheduler MAIN_THREAD_SCHEDULER =
                new HandlerScheduler(new Handler(Looper.getMainLooper()));
    }

    /** A {@link Scheduler} which executes actions on the Android UI thread. */
    public static Scheduler mainThread() {
        Scheduler scheduler =
                RxAndroidPlugins.getInstance().getSchedulersHook().getMainThreadScheduler();
        return scheduler != null ? scheduler : MainThreadSchedulerHolder.MAIN_THREAD_SCHEDULER;
    }
}

可以看到,scheduler就是一个 HandlerScheduler 对象,看HandlerScheduler类的实现:

public final class HandlerScheduler extends Scheduler {
    /*省略部分代码*/

    HandlerScheduler(Handler handler) {
        this.handler = handler;
    }

    @Override
    public Worker createWorker() {
        return new HandlerWorker(handler);
    }
		/*省略部分代码*/
    }
}

HandlerScheduler 类也继承了 Scheduler ,他的createWorker() 创建了一个HandlerWorker 对象。所以前面创建的worker其实就是 HandlerWorker。HandlerWorker 类是HandlerScheduler 的内部类,他的schedule 方法:

static class HandlerWorker extends Worker {

        private final Handler handler;

        private final CompositeSubscription compositeSubscription = new CompositeSubscription();

        HandlerWorker(Handler handler) {
            this.handler = handler;
        }
		
        @Override
        public Subscription schedule(Action0 action, long delayTime, TimeUnit unit) {
            if (compositeSubscription.isUnsubscribed()) {
                return Subscriptions.unsubscribed();
            }

            action = RxAndroidPlugins.getInstance().getSchedulersHook().onSchedule(action);

            final ScheduledAction scheduledAction = new ScheduledAction(action);
            scheduledAction.addParent(compositeSubscription);
            compositeSubscription.add(scheduledAction);

            handler.postDelayed(scheduledAction, unit.toMillis(delayTime));

            scheduledAction.add(Subscriptions.create(new Action0() {
                @Override
                public void call() {
                    handler.removeCallbacks(scheduledAction);
                }
            }));

            return scheduledAction;
        }

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

可以看到,在 schedule 内部还是创建了一个 ScheduledAction 对象,之后所有的操作都有他来完成。由前面分析可知,ScheduledAction 类实现了 Runnable。所以归根结底,两个线程控制都是由 Runnable 来实现的。


结语

我的源码解读就到这里了,希望对大家在学习RxJava的路上有所帮助。如果大家在阅读的过程中发现有什么错误的话可以评论或者私信我,谢谢支持!

编辑于 2016-11-14

文章被以下专栏收录