Rxjava的源码阅读日记(二)

上一次阅读了rxjava的基本流程启动的运作
本次将继续深一步阅读
这章类看看关于rxjava的线程切换原理
首先上一个基本代码

        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                e.onNext(1);
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });

rxjava用于切换线程的关键代码是:subscribeOn与observeOn这两个函数
找到方法后,当然就是进这个方法看看做了哪些动作,首先是subscribeOn的源码:

    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.CUSTOM)
    public final Observable<T> subscribeOn(Scheduler scheduler) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
    }

创建了一个ObservableSubscribeOn,进入ObservableSubscribeOn:

    public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
        super(source);
        this.scheduler = scheduler;
    }

    @Override
    public void subscribeActual(final Observer<? super T> s) {
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);

        s.onSubscribe(parent);

        parent.setDisposable(scheduler.scheduleDirect(new Runnable() {
            @Override
            public void run() {
                source.subscribe(parent);
            }
        }));
    }

从上一次章rxjava的流程阅读知道,observable的subscribe是整个流程的启动方法,而subscribe内部调用的正是subscribeActual方法
通过subscribeActual可以看到启动了Scheduler的scheduleDirect,并传入一个runnable,看到runnable大概能猜出来,里面应该就是线程启动的地方了,继续深入scheduleDirect:

  public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) {
        final Worker w = createWorker();
        final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
        w.schedule(new Runnable() {
            @Override
            public void run() {
                try {
                    decoratedRun.run();
                } finally {
                    w.dispose();
                }
            }
        }, delay, unit);
        return w;
    }

创建了一个Worker,并调用Worker的schedule,这个schedule有什么作用呢
我们先看一下Worker

 public abstract static class Worker implements Disposable

它只是一个抽象类,所以我们先找到实现类例子,就以io线程的Scheduler为例,首先找到它,我们知道Schedulers这个类维护了许多个线程的单一实例,如IO线程用于网络请求,COMPUTATION线程用于计算。
所以就在Schedulers里面找:

 static final Scheduler IO;

果然找到了,继续往下找它的实例化:

static {
        SINGLE = RxJavaPlugins.initSingleScheduler(new Callable<Scheduler>() {
            @Override
            public Scheduler call() throws Exception {
                return SingleHolder.DEFAULT;
            }
        });
        COMPUTATION = RxJavaPlugins.initComputationScheduler(new Callable<Scheduler>() {
            @Override
            public Scheduler call() throws Exception {
                return ComputationHolder.DEFAULT;
            }
        });
        IO = RxJavaPlugins.initIoScheduler(new Callable<Scheduler>() {
            @Override
            public Scheduler call() throws Exception {
                return IoHolder.DEFAULT;
            }
        });
        TRAMPOLINE = TrampolineScheduler.instance();
        NEW_THREAD = RxJavaPlugins.initNewThreadScheduler(new Callable<Scheduler>() {
            @Override
            public Scheduler call() throws Exception {
                return NewThreadHolder.DEFAULT;
            }
        });
    }

发现所有的线程都在static里面实例。我们只看io的:

        IO = RxJavaPlugins.initIoScheduler(new Callable<Scheduler>() {
            @Override
            public Scheduler call() throws Exception {
                return IoHolder.DEFAULT;
            }
        });

进入initIoScheduler你会发现,这个方法就只是单纯的一些null值判定,然后回调Callable.call,这里可以看到回调里面只有一行代码IoHolder.DEFAULT
这个是什么东西呢,我们在Schedulers里面找到它,是一个内部类:

    static final class IoHolder {
        static final Scheduler DEFAULT = new IoScheduler();
    }

终于看到IoScheduler,话不多说,看一下IoScheduler是什么

public final class IoScheduler extends Scheduler 

不出意外,继承了Scheduler ,所以我们回到最初的那个目的,找到它的Worder实现类:

static final class EventLoopWorker extends Scheduler.Worker

一个叫EventLoopWorker的家伙,里面维护了三个对象:CompositeDisposable、CachedWorkerPool、ThreadWorker,还有它的schedule方法,先看schedule方法:

        @Override
        public Disposable schedule(Runnable action, long delayTime, TimeUnit unit) {
            if (tasks.isDisposed()) {
                // don't schedule, we are unsubscribed
                return EmptyDisposable.INSTANCE;
            }

            return threadWorker.scheduleActual(action, delayTime, unit, tasks);
        }

调用了ThreadWorker.scheduleActual,看一下ThreadWorker是什么:

static final class ThreadWorker extends NewThreadWorker

继承的NewThreadWorder,继续看NewThreadWorder的scheduleActual

    public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, TimeUnit unit, DisposableContainer parent) {
        Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
        ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);
        if (parent != null) {
            if (!parent.add(sr)) {
                return sr;
            }
        }
        Future<?> f;
        try {
            if (delayTime <= 0) {
                f = executor.submit((Callable<Object>)sr);
            } else {
                f = executor.schedule((Callable<Object>)sr, delayTime, unit);
            }
            sr.setFuture(f);
        } catch (RejectedExecutionException ex) {
            parent.remove(sr);
            RxJavaPlugins.onError(ex);
        }
        return sr;
    }

发现里面有个executor对象,它是什么呢,我们来看看:

 private final ScheduledExecutorService executor;
public interface ScheduledExecutorService extends ExecutorService
public interface ExecutorService extends Executor

所以,Worker的schedule启动的正是Executor的schedule或submit
至此rxjava使用subscribeOn线程切换原理大致已经清楚,observeOn也是同理。
补充一点,关于主线程的切换原理,rxjava新增了一个rxandroid依赖,里面新维护了一个AndroidSchedulers类,我们是通过它来切换至主线程的。
那么来看看它的原理

public final class AndroidSchedulers {

    private static final class MainHolder {

        static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));
    }

    private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
            new Callable<Scheduler>() {
                @Override public Scheduler call() throws Exception {
                    return MainHolder.DEFAULT;
                }
            });

    /** A {@link Scheduler} which executes actions on the Android main thread. */
    public static Scheduler mainThread() {
        return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
    }

    /** A {@link Scheduler} which executes actions on {@code looper}. */
    public static Scheduler from(Looper looper) {
        if (looper == null) throw new NullPointerException("looper == null");
        return new HandlerScheduler(new Handler(looper));
    }

    private AndroidSchedulers() {
        throw new AssertionError("No instances.");
    }
}

切换很简单

static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));

就是使用了Looper.getMainLooper()。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值