Handler是如何传递消息的

小虫
2020-04-21 / 0 评论 / 275 阅读 / 正在检测是否收录...

先认识下跟Handler有关的几个类:MessageQueue,Message,Runnable,Looper。

  • Runnable和Message可以被传入某个MessageQueue中;
  • Looper不断地从MessageQueue中取出Object然后传给Handler进行处理,依次循环,如果队列为空,就会进入休眠;
  • Handler利用自身的处理机制对传入的Object进行相应的处理。

认识这几个类后,再了解下Handler和Thread的关系

  • 一个Thread对应一个Looper;
  • 一个Looper对应一个MessageQueue;
  • 一个MessageQueue对应N个Message;
  • 一个Message中对应一个Handle来处理事件;

由此可以看出,Thread和Handler是一对多的关系;而Handler主要有两个功能,处理message和将message传入MessageQueue中。
Looper从MessageQueue中取出一个Message后,首先会调用Handler.dispatchMessage进行消息分发,默认情况下Handler的分发流程是:

  1. Message.callback(Runnable obj) 如果不为空会优先调用callback处理
  2. Handler.mCallback 如果不为空会调用mCallback.handleMessage
  3. 如果以上两个对象都不存在,则会调用Handler.handleMessage

如果项目中有需要改变handler的默认行为,可以重载dispatchMessage或handleMessage。

Handler发送消息有两种方式,分别是post和send,这两种方式都是负责将message传入MessageQueue,区别在于send处理的参数直接是message,而post需要先把其它信息转换成message,再调用send来执行下一步,看源码:

public final boolean post(Runnable r){
   return sendMessageDelayed(getPostMessage(r),0);
}

因为调用时会传一个Runnable对象,post需要先将其封装成一个Message,接着通过对应的send把它传到MessageQueue里。

private static Message getPostMessage(Runnable r){
   Message m=Message.obtain();//Android系统会维护一个全局的Message池,当用户需要使用Message时,可以调和obtain获得,不用去自行创建,这样可以避免不必要的资源浪费
   m.callback=r;//将Runnable对象设置为Message的回调函数
   return m;
}

拿到Message后,再调用sendMessageDelayed来发送消息,这个函数可设置多长时间后再发送,在其内部又调用sendMessageAtTime来发送。

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
    }
    msg.target = this;
    return enqueueMessage(queue,msg,uptimeMillis);//将message传入MessageQueue
}

这样就将一条由Runnable组成的Message通过Handler成功传入MessageQueue。

0

评论 (0)

取消