每个 Android 开发者必须知道的消息机制问题总结
Android的消息机制几乎是面试必问的话题,当然也并不是因为面试,而去学习,更重要的是它在Android的开发中是必不可少的,占着举足轻重的地位,所以弄懂它是很有必要的。下面就来说说最基本的东西。
Looper
作用:
- 关联起Thread
- 循环取出消息
1、Looper是否可以直接实例化?
Looper构造方法是私有的,其中做了两件事
- 创建一个MessageQueue
- 得到与之对应的Thread
2、一个线程能对应多个Lopper?
不能,一个线程对应一个Looper对象,通过ThreadLocal保证一个线程只有一个Looper与之对应,如果多次调用Looper.prepare()
;则会抛出运行时异常。
3、Looper是无限循环,会阻塞吗?
是,当开启一个loop后是一个死循环,从MessageQueue中取出消息,处理消息,但是也有可能退出,在没有消息后退出循环。
4、可以再次调用Looper.prepareMainLooper吗?
不可以,Looper.prepareMainLooper最终也是调用prepare(),同2.
5、MainLooper什么时候创建的?
MainLooper是启动Activity创建ActivityThread(并不是一个Thread)时候创建,所以不能多次创建。
Handler
作用:
- 发送消息到MessageQueue
- 处理消息
1、Handler如何与Looper、MessageQueue关联起来?
我们知道一个Looper对应一个Thread,一个Looper包含一个MessageQueue。当我们创建Handler时就会从当前线程中取出与之对应的Looper,让后在从Looper中取出MessageQueue。
Message
单项链表结构。
作用:
- 数据的载体
1、消息如何复用的?
从全局消息池(链表结构)中
2、Message为什么能传递?
Android中想要传递对象要么实现Serializable要么Parcelable,在这里是实现了Parcelable接口。
3、如何与Handler关联?
我们知道在消息传机制中Handler充当着“快递员”的角色,那么他又是如何与“货物”--Message发生关系呢?实际上Message有一个成员变量target他的类型正是Handler,
当我们通过Handler去send一个Message时候最终都会为target赋值为this,即当前的Handler。
另为如果是通过Message.Obtain(),获取的复用Message也会为其赋值。
多说一句,Handler.obtainMessage()调用的就是Message.Obtain()。
总结:
通过一系列的包涵关系,最终Looper、Handler、Message、MessageQueue即发生关联,从而形成一个闭合,开启消息循环。
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- [译]谈谈SpringBoot 事件机制
- C++ 模板沉思录(下)
- Cocos2d-js中的简易MVC框架(四)显示层View
- 如何在去中心化交易所中(DEX)集成0x协议
- Spring Data REST不完全指南(二)
- Cocos2d-js中的简易MVC框架(三)中介者Mediator
- Cocos2d-js中的简易MVC框架(二)数据模型Model
- Python 还能实现图片去雾?FFA 去雾算法、暗通道去雾算法用起来! | 附代码
- 探秘计算机视觉中的注意力机制
- 采用 Vue 编写的功能强大的 Swagger-ui 页面
- Spring Data REST不完全指南(三)
- Spark Kafka 基于Direct自己管理offset
- 使用Reactor响应式编程
- 多场景下MySQL临时表的作用
- Flink 自定义触发器实现带超时时间的 CountWindow