6. Android 校招复习篇一・Handler
Handler
工作原理
概念
要了解原理首先我们要知道几个概念:
- Handler:处理器
- 定义1:
主线程与子线程的通信媒介 - 定义2:线程消息的主要处理者
- 作用:负责将消息
Message发送到消息队列MessageQueue以及处理循环器Looper分派过来的消息
- 定义1:
- MessageQueue:消息队列
- 定义:一种先进先出的数据结构
- 作用:用于存储
Handler发过来的消息Message
- Looper:循环器
- 定义:消息队列
MessageQueue与处理器Handler的通信媒介 - 作用:用于消息循环
- 消息获取:循环取出消息队列
MessageQueue里的消息Message - 消息分发:将取出的消息
Message发送给对应的处理器Handler
- 消息获取:循环取出消息队列
- 备注:
- 每个线程只能拥有1个Looper
- 1个Looper可绑定多个线程的Handler(即多个线程可往1个Looper所拥有的MessageQueue中发送消息,提供了线程间通信的可能)
- 定义:消息队列
工作流程
- 注意:
-
主线程的
Looper对象自动调用ActivityThread的静态方法main()中的Looper.prepareMainLooper()生成,同时会生成对应的MessageQueue对象;而子线程的Looper对象则需要手动通过Looper.prepare()创建-
在子线程若不手动创建
Looper对象,则无法生成Handler对象。在创建
Handler对象时,则通过构造方法自动关联当前线程的Looper对象 & 对应的消息队列对象MessagerQueue,从而自动绑定了实现创建Handler对象操作的线程。
-
-
在
Looper消息分发dispatchMessage(msg)时,会进行1次发送方式的判断(具体看源码):- 若
msg.callback属性不为空,则代表使用了post(Runnable r)发送消息,则回调Runnable对象里复写的run() - 若
msg.callback属性为空,则代表使用了sendMessage(Message msg)发送消息,则回调复写的handleMessage(msg)
- 若
-
常见面试问题
为什么Looper不断循环去处理消息却不会导致主线程卡死(ANR)?(2020蘑菇街面试真题)
系统每 16ms 会发送一个刷新 UI 消息唤醒。
Looper.loop()的死循环里面有两行代码:
|
|
这两行代码的作用就是从 消息队列MessageQueue 中不断地取出消息,然后把消息分发出去,给 Handler 处理,所以不会造成ANR。
因为 Android 是由事件驱动的,Looper.loop()不断地接收事件、处理事件,每一个点击触摸甚至是 Activity 的生命周期都是运行在Looper.loop()的控制下,如果他停止了,应用也随之停止了。
只能是某一个消息或者说对消息的处理阻塞了Looper.loop(),而不是Looper.loop()阻塞了它。
消息队列MessasgeQueue是一个什么样的结构?(2020蘑菇街面试真题)
存储特性为先进先出的数据结构,也就是队列
Handler/线程、Looper和MessageQueue的关系?(2020网易校招笔试原题)
Looper:负责从消息队列中拿消息,然后分发给线程中的 Handler 处理 MessageQueue:负责存储 Handler 发过来的消息 Handler:负责发消息到 MessageQueue 以及处理 Looper 分发过来的消息
Handler的post消息如何被执行?(2020网易校招笔试原题)