美文网首页
Handler(七)--Handler

Handler(七)--Handler

作者: azu_test | 来源:发表于2019-02-18 15:39 被阅读0次

    系列目录: Handler机制原理

    Handler使用介绍

    • 可实例化并通过它来发送消息
    • 重构里面的handleMessage()可实现接口回调

    主要代码分析

    1.send发送消息--sendMessage()
        public final boolean sendMessage(Message msg)
        {
            return sendMessageDelayed(msg, 0);
        }
    
        public final boolean sendMessageDelayed(Message msg, long delayMillis)
        {
            if (delayMillis < 0) {
                delayMillis = 0;
            }
            return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
        }
    
        public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
            MessageQueue queue = mQueue;
            if (queue == null) {
                RuntimeException e = new RuntimeException(
                        this + " sendMessageAtTime() called with no mQueue");
                Log.w("Looper", e.getMessage(), e);
                return false;
            }
            return enqueueMessage(queue, msg, uptimeMillis);
        }
    
        private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
            msg.target = this;
            if (mAsynchronous) {
                msg.setAsynchronous(true);
            }
            return queue.enqueueMessage(msg, uptimeMillis);
        }
    

    上面的代码大体就是普通消息转化为延时消息,然后延时消息转化为定时消息,然后把定时消息存入MessageQueue

    当然里面有七种send发送消息的方法,基本上都能归到这三种消息上。只要一种比较特殊sendMessageAtFrontOfQueue(),发送到表头上,最先取出并执行的消息。

    2. post发送消息--post()
        public final boolean post(Runnable r)
        {
           return  sendMessageDelayed(getPostMessage(r), 0);
        }
    
        public final boolean postDelayed(Runnable r, long delayMillis)
        {
            return sendMessageDelayed(getPostMessage(r), delayMillis);
        }
        
    
        public final boolean postAtTime(Runnable r, long uptimeMillis)
        {
            return sendMessageAtTime(getPostMessage(r), uptimeMillis);
        }
    
    • 从上面的代码可以看出post最终也都调用到上述send()那三个基本方法上了。
    • post(Runnable r),对于Runnable到底是怎么执行的,是开了单独的线程还是别的什么方法我们下面单独分析
    3. 消息分发 --dispatchMessage()

    Looper中我们已经分析到取出新的消息后会调用dispatchMessage()方法来分发消息。

        public void dispatchMessage(Message msg) {
            if (msg.callback != null) {
                //当Message存在回调方法,回调msg.callback.run()方法;
                handleCallback(msg);
            } else {
                if (mCallback != null) {
                    //当Handler存在Callback成员变量时,回调方法handleMessage();
                    if (mCallback.handleMessage(msg)) {
                        return;
                    }
                }
                //Handler自身的回调方法handleMessage()
                handleMessage(msg);
            }
        }
    

    这个方法很简单就是二个条件,三种情况

    情况1:如果msg.callback 不为空,则执行handleCallback(Message),而handleCallback(Message)的内部最终调用的是message.callback.run();,所以最终是msg.callback.run()。
    情况2:如果msg.callback 为空,且mCallback不为空,则执行mCallback.handleMessage(msg)。
    情况3:如果msg.callback 为空,且mCallback也为空,则执行handleMessage()方法

    分发消息时三个方法的优先级分别如下:

    • Message的回调方法优先级最高,即message.callback.run();
    • Handler的回调方法优先级次之,即Handler.mCallback.handleMessage(msg);
    • Handler的默认方法优先级最低,即Handler.handleMessage(msg)。
    4. Post(Runnable)怎么执行
        public final boolean post(Runnable r)
        {
           return  sendMessageDelayed(getPostMessage(r), 0);
        }
    

    上面方法里调用了getPostMessage ()方法来生成Message,我们看一下此方法源码

        private static Message getPostMessage(Runnable r) {
            Message m = Message.obtain();
            m.callback = r;
            return m;
        }
    

    上面方法生成了一个Message,并将Runnable赋给成员变量callback

    继续看一下消息分发的操作

        public void dispatchMessage(Message msg) {
            if (msg.callback != null) {
                handleCallback(msg);
            } else {
                if (mCallback != null) {
                    if (mCallback.handleMessage(msg)) {
                        return;
                    }
                }
                handleMessage(msg);
            }
        }
    

    通过消息分发的解析我们可以知道这里会执行handleCallback()方法。

        private static void handleCallback(Message message) {
            message.callback.run();
        }
    

    可以看到这里最终调用了Runnable#run()方法,所以没有开启新的线程,只是在源线程上执行的

    5. Handler发送消息方法整体图
    发送消息方法整体图

    相关文章

      网友评论

          本文标题:Handler(七)--Handler

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