底层要点简述
- 首先,底层实现了一个线程本地存储,叫
ThreadLocal区域,
一个主线程以及它对应的所有子线程,共享同一个 ThreadLocal对象,
这个ThreadLocal对象中可以说逻辑上维护着一个内存空间,
这个内存空间为不同的线程一 一 对应地维护一套数据副本,每一套数据副本对应着一个线程
(有多少线程共享这个ThreadLocal对象,ThreadLocal对象就准备多少套数据副本),
每一套数据副本在这里可以具体化为一个Object数组;
不同线程访问同一个ThreadLocal的get方法,
ThreadLocal内部会从(数据副本里)各自的线程中取出一个数组,
然后再从数组中根据当前ThreadLocal的索引去查找对应的value值。
比如对应线程的Looper,
ThreadLocal的索引值(key)就是唯一的静态的Looper对象(ThreadLocal<Looper>对应);
value就是不同线程自己的Looper对象;
- 而主线程及其所有子线程都可以开辟自己的
Looper,
每一个Looper都要绑定在一个Handler上,(如下方图1图2)
然后这些个每个单独的Looper,
都是Looper对应线程共享的ThreadLocal中某一个数据副本中的一个项的value,
这个项有key和value两部分,value是刚说的每一个线程对应的Looper,
而key则是存放在ThreadLocal中一个唯一的静态的Looper对象(ThreadLocal<Looper>)了,(如下方图3)
然后这个唯一的静态的Looper对象了关联着一个MessageQueue,
- 也就是说,
所有线程的Looper都映射到同一个Looper上,
所有线程的Looper中关联的MessageQueue也是映射到对应的同一个MessageQueue上;(如下方图1图2)
整个消息机制的工作流程常规表述
- 首先在需要传递消息的地方,我们构造一个
Message(消息)对象,
此时Message中会有自己的一个ID,
然后我们把需要传递的数据设置在这个Message里面,
借助Handler的sendMessage() 方法将Message传递到MessageQueue中,
此时MessageQueue通过调用MessageQueue.enqueueMessage()向MessageQueue自身中添加这条发送过来的Message;
MessageQueue(消息队列)中存放着诸多相关联的Handler发送过来的Message,
其内部通过单链表的数据结构来维护消息列表,
等待Looper的抽取。
Looper(消息泵)通过Looper.loop()不断轮询MessageQueue,
调用MessageQueue.next(),从MessageQueue中抽取队头的Message,
接着调用这个Message对应的Handler的dispatchMessage(),
将该Message传递分发给对应的Handler,
- 目标
Handler收到Message后调用handlerMessage()处理这个消息。

可以看一下这篇博客给ThreadLocal的关键分析Android(Java) | 如何使程序实现线程安全(拓展分析:ThreadLocal、重排序、volatile/final)
附图

Thread(线程):负责调度整个消息循环,即消息循环的执行场所。
存在关系:
- 一个Thread只能有一个Looper,可以有多个Handler;
- Looper有一个MessageQueue,可以处理来自多个Handler的Message;
- MessageQueue有一组待处理的Message,这些Message可来自不同的Handler;
- Message中记录了负责发送和处理消息的Handler;
- Handler中有Looper和MessageQueue;

