Android之Handler消息机制

Handler发送消息到队列,Looper从队列取出消息进行处理…

消息处理机制

  1. 消息发送,将消息放入队列。发送消息调用enqueueMessage将消息放入队列。mQuenue由mLooper创建。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
    MessageQueue queue = mQueue;
    ...
    return enqueueMessage(queue, msg, uptimeMillis);//加入消息队列
    }

    Handler的两个构造函数说明mQuenue由mLooper创建创建。
    1. public Handler(Callback callback, boolean async) {
    ...
    mLooper = Looper.myLooper();
    ...
    }

    2. public Handler(Looper looper, Callback callback, boolean async) {
    ...
    mQueue = looper.mQueue;
    ...
    }
  2. 消息循环。looper调用loop创建消息循环。从队列中获取消息并调用msg.target.dispatchMessage进行处理。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public static void loop() {
    ...
    final Looper me = myLooper();
    ...
    final MessageQueue queue = me.mQueue;
    ...
    Binder.clearCallingIdentity();//重置当前线程IPC(进程间通信)的标识符
    ...
    final long ident = Binder.clearCallingIdentity();
    ...
    msg.target.dispatchMessage(msg); //处理消息
    ...
    msg.recycleUnchecked();//将消息实例返回到全局池
    }
  3. 消息处理。msg.target.dispatchMessage(msg)处理消息,在Message中定义有一个字段target,在sendMessageAtTime的函数enqueueMessage中 有msg.target = this(代表发消息的Handler)。所以 消息由Handler的dispatchMessage处理。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
      private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
    msg.target = this;//给target赋值为当前handler
    if (mAsynchronous) {
    msg.setAsynchronous(true);
    }
    return queue.enqueueMessage(msg, uptimeMillis);
    }

    Handler的dispatchMessage
    public void dispatchMessage(Message msg) {
    ...
    handleCallback(msg);
    ...
    }
    }
    handleCallback只是调用callback(只是Runnable,一个赋值个Message的线程),最后消息传给了自定义的handleMessage;
    private static void handleCallback(Message message) {
    message.callback.run();
    }

handler消息机制分析简图

Handler消息机制

补充部分

关于looper与hander绑定如何绑定:

  1. 在主线程运行的绑定。 在主线程中运行的部分,都可以直接使用Handler,因为在主线程启动的过程中(ActivityThread的main函数里)会调用Looper.prepareMainLooper(),Looper类中也直接定义了一个static的looper实例sMainLooper用于存放主线程的Looper,可以通过静态方法获取到。 因此,凡是在主线程中运行的代码段里 都可以直接new Handler()而不用去绑定Looper,MessageQueue;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     public static void main(String[] args) {
    ...
    Looper.prepareMainLooper();//初始化当前线程作为一个Looper,并将之标记为应用的主Looper.

    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    if (sMainThreadHandler == null) {
    sMainThreadHandler = thread.getHandler();
    }
    ...
    }

    looper与handler绑定过程

    public Handler() {
    this(null, false);
    }
    this会使用如下handler。可知looper通过Looper.myLooper在线程中完成绑定
    public Handler(Callback callback, boolean async) {
    ...
    mLooper = Looper.myLooper();//返回与当前线程关联的looper对象
    ...
    mQueue = mLooper.mQueue;//返回与当前线程关联的消息队列
    ...
    }
  2. 在非主线程的绑定。在prepare函数中初始化了一个Looper,作为线程的一个成员变量。并将之放在ThreadLocal中。

    1
    2
    3
    4
    5
    6
    7
    8
    public static void prepare() {
    prepare(true);
    }
    然后调用:
    private static void prepare(boolean quitAllowed) {
    ...
    sThreadLocal.set(new Looper(quitAllowed));
    }
-------------本文结束感谢您的阅读-------------
鼓励鼓励!