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网易校招笔试原题)
