美文网首页
Handler、Looper、MessageQueue源码解析—

Handler、Looper、MessageQueue源码解析—

作者: windfall_ | 来源:发表于2017-05-13 23:12 被阅读0次


    Handler


    Handler 是Android中常用的异步通信的一个类,Android是一个消息驱动的操作系统,各种类型的消息都是由Handler发出,再由Handler处理,那么对于Handler机制的理解就至关重要。

    比如我们让一个TextView延时3秒显示"Hello World",我们会这样写:

    Handler mHandler = new Handler();
    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            mTextView.setText("Hello World");
        }
    }, 3000);```
    
    当我们new 一个Handler时,具体做了什么呢?从源码中我们可以得到
    答案:
    
    Handler共有7种构造方法:
    ```java
    Handler() 
    
    Handler(Callback callback)
    
    Handler(Looper looper)
    
    Handler(Looper looper, Callback callback)
    
    /**@hide*/
    Handler(boolean async)
    
    /**@hide*/
    Handler(Callback callback, boolean async)
    
    /**@hide*/
    Handler(Looper looper, Callback callback, boolean async)```
    
    (注意@hide注解,表示这些API是不对外开放的,但是在运行的时候是可以使用这些API。虽然也是public的,但是不能直接调用,也无法通过反射获取。所以我们在使用Handler时只能用前四个构造方法。)
    
    根据传入参数的不同,最后都会调用这两个构造方法:
    
    ``` java
    //没有传Looper
    Handler(Callback callback, boolean async)
    //传了Looper
    Handler(Looper looper, Callback callback, boolean async)```
    
    至于Looper是什么,接下来再解释。
    
    看一下```Handler(Callback callback, boolean async)```这个构造函数:
    
    ``` java
    
        final Looper mLooper;
        final MessageQueue mQueue;
        final Callback mCallback;
        final boolean mAsynchronous;
    
        ...
    
        public Handler(Callback callback, boolean async) {
            //检查Handler类型,提示是否出现内存泄漏warning
            if (FIND_POTENTIAL_LEAKS) {
                final Class<? extends Handler> klass = getClass();
                if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                        (klass.getModifiers() & Modifier.STATIC) == 0) {
                    Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                        klass.getCanonicalName());
                }
            }
            
            // 得到Looper对像,稍后解释
            mLooper = Looper.myLooper();
            if (mLooper == null) {
                throw new RuntimeException(
                    "Can't create handler inside thread that has not called Looper.prepare()");
            }
            //获得MessageQueue对象
            mQueue = mLooper.mQueue;
            //设置callback
            mCallback = callback;
            mAsynchronous = async;
        }```
    首先通过```Looper.myLooper()```获得Looper对象,再通过Looper对象获取与Looper绑定的MessageQueue对象。
    
    那么```Handler(Looper looper, Callback callback, boolean async)```这个构造函数呢?
    
    ``` java
        public Handler(Looper looper, Callback callback, boolean async) {
            mLooper = looper;
            mQueue = looper.mQueue;
            mCallback = callback;
            mAsynchronous = async;
        }```
    没错,区别就是Looper对象通过我们传进来的Looper对象来指定。
    
    既然Handler是发送消息和处理消息的,那么Handler是怎么发送消息的呢?
    
    官方为我们提供了这些方法:
    
    ```java
    public final boolean post(Runnable r)
    public final boolean postAtTime(Runnable r, long uptimeMillis)
    public final boolean postDelayed(Runnable r, long delayMillis)
    public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)
    public final boolean sendMessage(Message msg)
    public final boolean sendEmptyMessage(int what)
    public final boolean sendEmptyMessageDelayed(int what, long delayMillis)
    public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis)
    public final boolean sendMessageDelayed(Message msg, long delayMillis)
    public boolean sendMessageAtTime(Message msg, long uptimeMillis)```
    
    看起来很多,其实最后都调用了一个方法```sendMessageAtTime(Message msg, long uptimeMillis)```。
    
    什么?道理我都懂,post(Runnable r)是个什么东西?
    其实post一系列方法最后调用的还是```sendMessageAtTime(Message msg, long uptimeMillis)```。
    
    但是第一个参数传进去的是getPostMessage(r)
    ``` java
        private static Message getPostMessage(Runnable r) {
        //从Message pool里获得一个Message或者新建一个Message对象
            Message m = Message.obtain();
            m.callback = r;
            return m;
        }
    

    可以看出Runnable是Message的callback。Runnable callback是Message的一个成员变量,所以postXXX方法就是对Message的一个封装。

    那么我们重点看一下sendMessageAtTime方法。

        public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        //从Looper中获得的MessageQueue
            MessageQueue queue = mQueue;
            if (queue == null) {
                RuntimeException e = new RuntimeException(
                        this + " sendMessageAtTime() called with no mQueue");
                Log.w("Looper", e.getMessage(), e);
                return false;
            }s
            return enqueueMessage(queue, msg, uptimeMillis);
        }```
    
    最后调用enqueueMessage方法:
    ``` java
        private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
            msg.target = this;
            if (mAsynchronous) {
                msg.setAsynchronous(true);
            }
            return queue.enqueueMessage(msg, uptimeMillis);
        }```
    
    target是Message的一个Handler类型的成员变量。所以sendMessageAtTime方法就是获取MessageQueue,并为Message对象设置target属性,然后把message插入到MessageQueue中。
    
    Handler也提供了另外两个方法,直接把消息插入到消息队列第一个:
      ```java
    public final boolean postAtFrontOfQueue(Runnable r)
    public final boolean sendMessageAtFrontOfQueue(Message msg)```
    
    说完了发送消息,接下来说一下处理消息。
    
    在Looper的 ``` loop()``` (开启消息循环)方法有这样一段代码:
    
    try {
        msg.target.dispatchMessage(msg);
    } finally {
        if (traceTag != 0) {
            Trace.traceEnd(traceTag);
        }
    }```
    

    我们已经知道message的target是一个Handler对象,消息的处理也就是调用了Handler的dispathMessage方法:

        public void dispatchMessage(Message msg) {
            if (msg.callback != null) {
                handleCallback(msg);
            } else {
                if (mCallback != null) {
                    if (mCallback.handleMessage(msg)) {
                        return;
                    }
                }
                handleMessage(msg);
            }
        }```
    首先判断message的callback是否为空,即我们通过postXXX方法发送的消息会给Message加上一个callback即Runnable,如果不为空调用handleCallback(msg):
    ``` java
        private static void handleCallback(Message message) {
            message.callback.run();
        }```
    也就是调用Runnable的run()方法。
    
    如果Message的Callback为空,接下来判断mCallback是否为空,mCallback是什么呢,回到Handler的构造方法,当我们调用这两个构造方法```Handler(Callback callback) , Handler(Looper looper, Callback callback)```时,我们会为Handler指定一个callback,当Handler的callback不为空,会执行callback的handleMessage方法,如果callback为空,则执行Handler的handleMessage方法,这两个方法的实现都为空,需要我们自己去实现。
    
    Handler的源码大部分就是这么多,其余的就是一些removeCallback之类的方法。Handler的主要功能就是这些。接下来我们来学习其他两个很重要的类Looper。

    相关文章

      网友评论

          本文标题:Handler、Looper、MessageQueue源码解析—

          本文链接:https://www.haomeiwen.com/subject/gugxxxtx.html