news 2026/3/9 13:44:21

从 C 链表到 Android Looper:MessageQueue 的底层原理一条线讲透

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从 C 链表到 Android Looper:MessageQueue 的底层原理一条线讲透

前言:为什么要从 C 链表讲起?

很多 Android 开发者都用过Handler / Looper / MessageQueue
但一深入源码就会觉得“抽象、复杂、难以下手”。

其实问题不在 Android,而在于我们没把底层模型串起来

如果你愿意退回一步,用C 语言最基础的数据结构视角去看,就会发现:

Android 的消息机制,本质就是:
链表 + 队列 + 排序 + 阻塞循环。

本文尝试做一件事:
👉从 C 语言的链表出发,一步一步推导到 Android 的 MessageQueue / Looper
把这条逻辑链完整走一遍。

一、指针的本质:一切从“地址”开始

在 C 语言中:

int x = 10; int *p = &x;
  • x是一个值
  • &x是 x 的内存地址
  • p是一个存地址的变量
  • *p表示“通过地址访问那块内存里的值”

指针 = 存地址的变量

这是后面所有数据结构的根基。

这一点非常重要,因为:

  • 链表
  • 队列
  • MessageQueue
  • Looper

全部建立在“地址关系”之上。

二、为什么需要 struct?

单个变量无法表达复杂对象,我们需要把“相关数据”组织在一起:

struct Person { int age; int height; };

struct的本质只是:
👉一块内存的布局说明书

它本身并不负责逻辑。

三、Node:链表的最小原子结构

链表的核心是Node

typedef struct Node { void *data; // 指向真实数据 struct Node *next; // 指向下一个节点 } Node;

这里有两个完全不同层次的指针:

  • data业务数据指针

  • next结构关系指针

一句话总结:

Node = 数据 + 指向下一个 Node 的关系

多个 Node 通过next串起来,就形成了链表:

Node1 -> Node2 -> Node3 -> NULL

四、为什么“只有 Node”是没用的?

此时会遇到一个致命问题:

👉从哪里开始遍历?

链表必须有一个“入口”,也必须有人维护整体状态。

五、Queue:Node 的管理者(系统思维的起点)

于是我们引入“管理结构”:

typedef struct { Node *head; Node *tail; int size; } Queue;

现在结构关系变成:

Queue ├── head ──> Node ──> Node ──> Node ──> NULL ├── tail ────────────────────────────┘ └── size

注意一个非常重要的事实:

Queue 自己不存数据,它只负责“管理 Node 的关系”。

这是从“数据结构”走向“系统设计”的第一步。

六、为什么Queue*不需要二级指针?

初始化 Queue 通常这样写:

Queue q; queue_init(&q);
void queue_init(Queue *q) { q->head = NULL; q->tail = NULL; q->size = 0; }

这里:

  • q本体已经存在(在栈上)

  • 函数只是修改Queue内部字段

  • 并没有修改指针变量本身

所以:
👉一级指针足够

七、什么时候才需要二级指针?

只有一种情况:

当函数需要“创建 / 替换一个指针变量本身”

void create_queue(Queue **pq) { *pq = malloc(sizeof(Queue)); }

调用方式:

Queue *q = NULL; create_queue(&q);

这里的本质是:

  • q是一个Queue*指针变量

  • &q的类型是Queue**

  • Queue**正好能“接住”&q

  • *pq = malloc(...)本质是给q重新赋值

👉二级指针的本质是“类型匹配 + 写回指针变量”

八、从 Queue 到 MessageQueue:关键差异只有一个

普通 Queue 是FIFO

Android 的 MessageQueue 不一样,它是:

按执行时间排序的消息队列

因此 Node 演化为 Message:

typedef struct Message { long when; // 什么时候执行 void (*callback)(void); // 要执行的任务 struct Message *next; } Message;

你会发现:

  • 结构没变

  • 指针没变

  • 只是数据字段更“业务化”

九、MessageQueue 的核心职责

MessageQueue 主要做三件事:

  1. when有序插入 Message

  2. 维护单向链表

  3. 提供next()获取“当前可执行的消息”

它不是简单的队列,而是“时间有序链表”。

十、Looper:系统的“心跳循环”

Looper 的逻辑可以简化成一句话:

for (;;) { Message *msg = queue.next(); dispatch(msg); }

也就是说:

Looper = 无限循环 + 从 MessageQueue 取消息并执行

这就是 Android UI 线程的“发动机”。

十一、为什么 Looper 不会空转卡死?

关键在MessageQueue.next()

  • 如果队列为空

  • 或最近一条消息还没到执行时间

👉线程进入阻塞状态

当:

  • 新消息入队

  • 或时间到达

👉线程被唤醒

因此:

next() ≠ pop()
next() = “能执行才返回,否则阻塞等待”

这是系统层设计的精髓。

十二、完整映射关系一览

C 世界Android 世界
NodeMessage
next 指针Message.next
QueueMessageQueue
for(;;)Looper.loop()
阻塞等待native poll / wake
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/8 9:04:31

5个必学技巧!让你的点云可视化性能提升200%

5个必学技巧!让你的点云可视化性能提升200% 【免费下载链接】rerun Visualize streams of multimodal data. Fast, easy to use, and simple to integrate. Built in Rust using egui. 项目地址: https://gitcode.com/GitHub_Trending/re/rerun 你是否在加载…

作者头像 李华
网站建设 2026/3/6 13:09:56

轻量级图表库uPlot完全指南:解锁高性能可视化新境界

轻量级图表库uPlot完全指南:解锁高性能可视化新境界 【免费下载链接】uPlot 📈 A small, fast chart for time series, lines, areas, ohlc & bars 项目地址: https://gitcode.com/gh_mirrors/up/uPlot 想要在网页中流畅展示大量时间序列数据…

作者头像 李华
网站建设 2026/3/6 9:39:41

35、本地化与国际化文本函数详解

本地化与国际化文本函数详解 1. 字符串转换操作 在处理输入字符串时,根据 XIMStringConversionOperation 的不同类型,客户端的操作也有所不同: - 当 XIMStringConversionOperation 为 XIMStringConversionSubstitution 时,客户端必须从自身缓冲区中删除待转换的字…

作者头像 李华
网站建设 2026/3/6 9:39:39

AdGuard Home配置优化实战指南:从新手到专家的5个关键步骤

AdGuard Home配置优化实战指南:从新手到专家的5个关键步骤 【免费下载链接】AdGuardHome Network-wide ads & trackers blocking DNS server 项目地址: https://gitcode.com/gh_mirrors/ad/AdGuardHome 你是否遇到过AdGuard Home安装后广告拦截效果不佳&…

作者头像 李华
网站建设 2026/3/9 10:22:19

3步上手FLAN-T5 XL:从零开始掌握强大语言模型

3步上手FLAN-T5 XL:从零开始掌握强大语言模型 【免费下载链接】flan-t5-xl 项目地址: https://ai.gitcode.com/hf_mirrors/google/flan-t5-xl FLAN-T5 XL是Google推出的先进语言模型,基于T5架构进行指令微调,在文本生成、翻译、问答等…

作者头像 李华
网站建设 2026/3/6 9:39:37

5分钟快速上手:awesome-godot项目带你玩转游戏开发

5分钟快速上手:awesome-godot项目带你玩转游戏开发 【免费下载链接】awesome-godot A curated list of free/libre plugins, scripts and add-ons for Godot 项目地址: https://gitcode.com/gh_mirrors/aw/awesome-godot 想要轻松入门游戏开发却不知从何开始…

作者头像 李华