Tip | Android的消息机制

底层要点简述

  • 首先,底层实现了一个线程本地存储,叫ThreadLocal区域,
    一个主线程以及它对应的所有子线程,共享同一个 ThreadLocal对象,
    这个ThreadLocal对象中可以说逻辑上维护着一个key-value表
    这个表为不同的线程一 一 对应地维护一套数据副本
    每一套数据副本对应着一个线程
    (有多少线程共享这个ThreadLocal对象,ThreadLocal对象就准备多少套数据副本),
    每一套数据副本也是ThreadLocal对象中这个逻辑key-value表的一个项
    数据副本在这里可以具体化为Looper对象
  • 而主线程及其所有子线程都可以开辟自己的Looper
    每一个Looper都要绑定在一个Handler上,(如下方图1图2)
    然后这些个每个Looper都是共享的ThreadLocal中逻辑表的一个项,
    这个项有keyvalue两部分,
    value是每一个线程对应的Looper
    而key则是存放在ThreadLocal中一个唯一的静态的Looper对象了,(如下方图3)
    然后这个唯一的静态的Looper对象了关联着一个MessageQueue

  • 也就是说,所有线程的Looper都映射到同一个Looper上,
    所有线程的Looper中关联的MessageQueue也是映射到对应的同一个MessageQueue上;(如下方图1图2)


整个消息机制的工作流程常规表述

  • 首先在需要传递消息的地方,我们构造一个Message(消息)对象,
    此时Message中会有自己的一个ID
    然后我们把需要传递的数据设置在这个Message里面,
    借助HandlersendMessage() 方法将Message传递到MessageQueue中,
    此时MessageQueue通过调用MessageQueue.enqueueMessage()MessageQueue自身中添加这条发送过来的Message

  • MessageQueue(消息队列)中存放着诸多相关联的Handler发送过来的Message
    其内部通过单链表的数据结构来维护消息列表,
    等待Looper的抽取。

  • Looper(消息泵)通过Looper.loop()不断轮询MessageQueue
    调用MessageQueue.next(),从MessageQueue中抽取队头的Message
    接着调用这个Message对应的HandlerdispatchMessage()
    将该Message传递分发给对应的Handler

  • 目标Handler收到Message后调用handlerMessage()处理这个消息。

Tip | Android的消息机制
图0

附图

Tip | Android的消息机制
图1

Thread(线程):负责调度整个消息循环,即消息循环的执行场所。
存在关系:

  • 一个Thread只能有一个Looper,可以有多个Handler;
  • Looper有一个MessageQueue,可以处理来自多个Handler的Message;
  • MessageQueue有一组待处理的Message,这些Message可来自不同的Handler;
  • Message中记录了负责发送和处理消息的Handler;
  • Handler中有Looper和MessageQueue;
Tip | Android的消息机制
图2

Tip | Android的消息机制
图3

参考资料: