之前研究过Handler机制,重点看了Handler、Looper、MessageQueue、ThreadLocal这几个类,其中Message源码没仔细看,现在过一遍。

可以看出message是链表结构。没有pre,单链表。
另外, target就是处理这个消息的Handler对象。when是消息处理时间。callback是处理消息时执行的回调。不详细看了。
再看下消息复用:

sPool意思是消息对象池,存的是一个Message链表头节点。obtain方法从对象池中取头节点。然后断开和池链表的链接。当对象池为空时才new Message()。
再看下recycleUnchecked方法,看下Message何时回收:

这里有几个关键点:
字段清零:防止复用 Message 时携带旧数据,尤其是 target、callback、obj、data;
头插法回池:next = sPool; sPool = this; 把当前正在回收的Message 插到Message消息池链表的头部;
池上限 50:超过就不再缓存,交给 GC。
isAsynchronous方法:

看下在MessageQueue中怎么用的。

这里意思是,被屏障(Barrier)阻塞,查找队列中的下一条异步消息。即,当前消息队列遇到了一个同步屏障,导致普通同步消息无法执行;因此,系统需要跳过这些被阻塞的消息,去查找并执行下一条允许穿过屏障的异步消息。 可以看到这种场景 message的target属性为null,不是app中产生的消息。核心场景是:Android 主线程(UI 线程)的消息队列中插入了"同步屏障"(Sync Barrier),且此时需要优先处理高优先级的异步任务(如 UI 绘制、输入事件响应)时。系统框架层(而非普通应用代码)通过调用 MessageQueue.postSyncBarrier() 向消息队列插入这条消息。
典型应用场景:UI 渲染与 VSYNC 信号
这是这段代码最主要、最核心的应用场景。
背景问题: Android 屏幕刷新依赖 VSYNC 信号(通常每 16.6ms 一次)。当 VSYNC 信号到来时,系统需要立即执行 UI 的测量、布局、绘制流程(Choreographer 触发的 Traversal)。如果此时主线程消息队列中堆积了大量的普通同步消息(如网络回调、数据库操作、普通的 post(Runnable)),UI 绘制任务就得排队等待,导致掉帧、卡顿。
解决方案:
在 VSYNC 信号到来前,系统会调用 postSyncBarrier() 插入一个同步屏障。
随后,系统将 UI 绘制任务封装为异步消息(msg.setAsynchronous(true))并发送入队。
当 Looper 循环取消息时,执行到这段代码:
检测到屏障(target == null)。
跳过所有后续的普通同步消息(即使它们的时间戳已经到了)。
查找并取出第一个标记为异步的消息(即 UI 绘制任务)。
UI 绘制任务得以"插队"优先执行,保证在下一个帧周期开始前完成渲染。
绘制完成后,系统调用 removeSyncBarrier() 移除屏障,普通同步消息恢复执行。