相关问题
Q1:主线程 Looper.loop() 是死循环,为什么不卡死、不耗电?
没消息时 queue.next() 阻塞在 nativePollOnce → epoll_wait,线程休眠,不消耗 CPU。ANR 也不是"循环卡住",而是某条消息处理超过阈值(Activity 5s、Service 20s、前台广播 10s),由 AMS 侧监测触发。
Q2:为什么子线程 new Handler() 会崩?
构造里 Looper.myLooper() 拿不到就抛 Can't create handler inside thread ... that has not called Looper.prepare()。子线程必须先 Looper.prepare(),再 Looper.loop()。
Q3:postDelayed(1000) 精确吗?
不精确。when = uptimeMillis() + delay,实际执行还取决于前面是否有未处理完的消息、消息自身耗时。且 uptimeMillis() 不包含深睡时间(要含睡眠得用 elapsedRealtime())。
Q4:MessageQueue 为什么用单链表,不用数组 / PriorityQueue?
插入是按 when 有序插入,链表 O(n) 但常数极小、无扩容、无搬移;而且 Message.next 天然复用为对象池的链表指针。队列长度通常很小,实测比堆结构更快更省。
Q5:Handler 和 Binder 的区别?
Handler 是同进程内线程间通信;跨进程是 Binder(以及封装它的 Messenger / AIDL)。本篇的边界是"进程内",不涉及 IPC。
Q6:一个线程能有几个 Looper / MessageQueue / Handler?
Looper 和 MessageQueue 各一个(第二次 prepare() 抛 Only one Looper may be created per thread);Handler 可以有多个,共享同一个队列。