Handler(七)--Handler

2019-02-18  本文已影响0人  azu_test

系列目录: 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发送消息方法整体图
发送消息方法整体图
上一篇 下一篇

猜你喜欢

热点阅读