• Android 中有两个 Handler,分别是 HandlerA和 HandlerB,如果在A中post一个延时任务,在 HandlerB 中 remove 这个任务,会发生什么?(字节)
  • 结论:无法 remove
  • 因为 Message 被创建的时候会指定 Hanlder target 成员,保证了一个 Message 只能被特定的 Handler 操作
  • Handler 如何保证延时任务的正确执行
  • 设置 Message 对象的 when 参数:使用 delayMillis + SystemClock.uptimeMillis() (设备自启动后经过的毫秒数,不受系统时间改变影响,是单调递增的)获得一个 when 的时间戳
  • 如何 Message 带有 when 字段,enqueueMessage 方法不会简单地将消息添加到队尾,而是遍历队列,插到合适的位置
  • 情况 A: 消息已到期: 如果队首消息的 when 时间戳小于或等于当前的 SystemClock.uptimeMillis(),说明这条消息已经到期或过期,next() 将其从队列中移除并返回给 Looper
  • 情况 B: 消息未到期: 如果队首消息的 when 时间戳大于当前的 SystemClock.uptimeMillis(),说明最早的消息也还没到执行时间。此时:next() 计算出需要等待的时间 delay = headMessage.when - SystemClock.uptimeMillis()
  • 它调用底层的 nativePollOnce(ptr, delay) 方法。这个 native 方法会使当前线程阻塞,但不是无限期阻塞,而是最多阻塞 delay 毫秒。它利用了操作系统的机制(如 Linux 的 epoll_wait)来实现高效的定时等待。
  • 如果在阻塞期间,有新的、更早到期的消息被插入到队首(通过 enqueueMessage),或者阻塞时间到达 delay 毫秒,nativePollOnce 就会被唤醒,next() 方法继续执行,重新检查队首消息。
  • Hanlder 如何维护消息的顺序?
  • 因为是链表,只能从头节点开始遍历并插入