RxAndroid解析

本文出自:【InTheWorld的博客】

首先说明,RxAndroid其实并不是一个大项目,它更接近于一个RxJava在Android平台的一个补丁。不过这个霸气的名字却容易让人感觉这个一个平行的大项目。其实RxJava在Android上特殊性主要体现在UI线程的切换上,因为Android不允许普通线程更新UI。所以,RxAndroid的主要功能其实就是实现了AndroidSchedulers的功能。对于AndroidSchedulers这个类而言,我们最熟悉的用法便是AndroidSchedulers.mainThread()这个方法了。

public final class AndroidSchedulers {
    private static final AtomicReference INSTANCE = new AtomicReference<>();
    private final Scheduler mainThreadScheduler;
    private static AndroidSchedulers getInstance() {
        for (;;) {
            AndroidSchedulers current = INSTANCE.get();
            if (current != null) {
                return current;
            }
            current = new AndroidSchedulers();
            if (INSTANCE.compareAndSet(null, current)) {
                return current;
            }
        }
    }
    private AndroidSchedulers() {
        RxAndroidSchedulersHook hook = RxAndroidPlugins.getInstance().getSchedulersHook();

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

上面这段代码就是AndroidSchedulers类比较核心的代码,这个类也是一个单例类。mainThread()是一个静态方法,它的返回值是一个Scheduler。getInstance()其实很容易理解,就是返回一个唯一存在的AndroidSchedulers实例。在这个类的构造方法中,使用了一个RxAndroidSchedulersHook类。这个类看似玄乎,但其实目前并没有什么用处。它的getMainThreadScheduler()方法一定会返回null。不信?你看RxAndroidSchedulersHook的代码:

    public Scheduler getMainThreadScheduler() {
        return null;
    }

所以,mainThread()返回的其实一个LooperScheduler(Looper.getMainLooper())。如果对Android的Handler机制比较了解的话,那么对Looper.getMainLooper()也不会陌生。这里我们简单的回顾一下这个知识点,Looper与Handler。首先,顾名思义就知道Looper其实就是一个不断循环的服务线程,根据客户端的请求进行相应的处理。对于Android的UI线程来说,mainLooper就相当于一个“图形服务器”,根据其他线程的绘制请求来更新UI。相应的,Handler就是一个详细的请求,之所以说它很详细,是因为它会提供相应的执行方法,主线程只需要调用相应的方法即可。理论分析了这么多,还是看看源码来一探究竟。Looper的部分核心代码如下:

public class Looper {
    private static final ThreadLocal sThreadLocal = new ThreadLocal();
    final MessageQueue mQueue;
    Thread mThread;
    private Looper() {
        mQueue = new MessageQueue();
        mRun = true;
        mThread = Thread.currentThread();
    }

    public static final void loop() {
        // 进入当前线程的消息循环
        Looper me = myLooper();
        MessageQueue queue = me.mQueue;
        while (true) {
            // 从队列中取出消息
            Message msg = queue.next(); // might block
            if (msg != null) {
                // 分发消息
                msg.target.dispatchMessage(msg);
                // 消息的target是Handler类型的对象
                // 释放清理
                msg.recycle();
            }
        }
    }
}

Handler就前面说的消息,也就是上面代码段的target成员。在这里, 我们可以猜测,LooperScheduler就是对Handler进行了一些封装和适配,从功能原理上和Handler基本一样。LooperScheduler的主要功能都是由两个内部类完成的,分别是HandlerWorker和ScheduledAction。其中,HandlerWorker主要实现了发送Message的功能,而ScheduledAction主要完成了Handler管理的功能。这里主要看看HandlerWorker干了什么?主要代码如下:

        public Subscription schedule(Action0 action, long delayTime, TimeUnit unit) {
            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;
        }

最核心的代码就是handler.sendMessageDelayed()这行,标准的Handler使用方法,看起来非常的熟悉。好吧!RxAndroid其实就是这么简单。这篇博客也就到这里了。。。

发表评论