山西电力建设三公司网站网页制作三剑客包括
2026/4/18 2:56:04 网站建设 项目流程
山西电力建设三公司网站,网页制作三剑客包括,组织建设六个方面内容,创新的成都 网站建设前言#xff1a;为什么要从 C 链表讲起#xff1f; 很多 Android 开发者都用过 Handler / Looper / MessageQueue#xff0c; 但一深入源码就会觉得“抽象、复杂、难以下手”。 其实问题不在 Android#xff0c;而在于我们没把底层模型串起来。 如果你愿意退回一步…前言为什么要从 C 链表讲起很多 Android 开发者都用过Handler / Looper / MessageQueue但一深入源码就会觉得“抽象、复杂、难以下手”。其实问题不在 Android而在于我们没把底层模型串起来。如果你愿意退回一步用C 语言最基础的数据结构视角去看就会发现Android 的消息机制本质就是链表 队列 排序 阻塞循环。本文尝试做一件事从 C 语言的链表出发一步一步推导到 Android 的 MessageQueue / Looper把这条逻辑链完整走一遍。一、指针的本质一切从“地址”开始在 C 语言中int x 10; int *p x;x是一个值x是 x 的内存地址p是一个存地址的变量*p表示“通过地址访问那块内存里的值”指针 存地址的变量这是后面所有数据结构的根基。这一点非常重要因为链表队列MessageQueueLooper全部建立在“地址关系”之上。二、为什么需要 struct单个变量无法表达复杂对象我们需要把“相关数据”组织在一起struct Person { int age; int height; };struct的本质只是一块内存的布局说明书它本身并不负责逻辑。三、Node链表的最小原子结构链表的核心是Nodetypedef struct Node { void *data; // 指向真实数据 struct Node *next; // 指向下一个节点 } Node;这里有两个完全不同层次的指针data业务数据指针next结构关系指针一句话总结Node 数据 指向下一个 Node 的关系多个 Node 通过next串起来就形成了链表Node1 - Node2 - Node3 - NULL四、为什么“只有 Node”是没用的此时会遇到一个致命问题从哪里开始遍历链表必须有一个“入口”也必须有人维护整体状态。五、QueueNode 的管理者系统思维的起点于是我们引入“管理结构”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 演化为 Messagetypedef struct Message { long when; // 什么时候执行 void (*callback)(void); // 要执行的任务 struct Message *next; } Message;你会发现结构没变指针没变只是数据字段更“业务化”九、MessageQueue 的核心职责MessageQueue 主要做三件事按when有序插入 Message维护单向链表提供next()获取“当前可执行的消息”它不是简单的队列而是“时间有序链表”。十、Looper系统的“心跳循环”Looper 的逻辑可以简化成一句话for (;;) { Message *msg queue.next(); dispatch(msg); }也就是说Looper 无限循环 从 MessageQueue 取消息并执行这就是 Android UI 线程的“发动机”。十一、为什么 Looper 不会空转卡死关键在MessageQueue.next()如果队列为空或最近一条消息还没到执行时间线程进入阻塞状态当新消息入队或时间到达线程被唤醒因此next() ≠ pop()next() “能执行才返回否则阻塞等待”这是系统层设计的精髓。十二、完整映射关系一览C 世界Android 世界NodeMessagenext 指针Message.nextQueueMessageQueuefor(;;)Looper.loop()阻塞等待native poll / wake

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询