Android_Question
Android_Question copied to clipboard
Handler机制如何保证消息不错乱?消息延迟是如何实现的?Handler、Looper、MessageQueue三者对应关系?内存泄漏如何避免?Looper中的死循环为什么不会引器主线程ANR?
1.handler机制中多个handler共有一个looper不会错乱是因为在handler 发送消息的时候,会将当前的handler对象绑定到message的target属性上,然后在Looper取到消息后通过msg.target拿到之前的handler对象,然后调用handler的handleMessage方法。
2.消息延迟的原理:handler发送延迟消息,会将当前的延迟时间绑定到msg的when属性上,然后在循环MessageQUeue获取msg时判断如果当前有延迟就进行阻塞,通过计时器计算时间,时间通过系统启动计算时间,然后等待阻塞时间结束之后将其唤醒,在阻塞过程中会将之后的消息放在消息队列的头部去处理。
3.同一个线程中可以有多个Handler,只有一个Looper,而MessageQueue在looper中初始化的,所以也只有一个MessageQueue。因此对应关系是:Handler:Looper = 多对一,Looper:MeesageQueue = 一对一,Handler:MessageQueue = 多对一。
4.Handler的内存泄漏是由于Handler持有外部类的引用,使其无法释放。 解决办法:(1)定义成静态内部类,使其不持有外部类的引用;(2)可以使用弱引用; 还需要在外部类销毁的时候,移除所有的消息。
5.可以说整个应用的生命周期都是在looper.loop()控制之下的(在应用启动的入口main函数中初始化ActivityThread,Handler,Looper,然后通过handler和looper去控制初始化应用)。而looper.loop采用的是Linux的管道机制,在没有消息的时候会进入阻塞状态,释放CPU执行权,等待被唤醒。真正会卡死主线程的操作是在回调方法onCreate/onStart/onResume等操作时间过长,会导致掉帧,甚至发生ANR,looper.loop本身不会导致应用卡死。