我对安卓handler机制的理解

handler机制,在android中提供了一种异步回调机制Handler,使用它,我们可以在完成一个很长时间的任务后做出相应的通知。

每一个消息都需要被指定的Handler处理,通过Handler创建消息便可以完成此功能。Android消息机制中引入了消息池。Handler创建消息时首先查询消息池中是否有消息存在,如果有直接从消息池中取得,如果没有则重新初始化一个消息实例。使用消息池的好处是:消息不被使用时,并不作为垃圾回收,而是放入消息池,可供下次Handler创建消息时使用。消息池提高了消息对象的复用,减少系统垃圾回收的次数。消息的创建流程如图所示。

技术分享

UI主线程初始化第一个Handler时会通过ThreadLocal创建一个Looper,该LooperUI主线程一一对应。使用ThreadLocal的目的是保证每一个线程只创建唯一一个Looper。之后其他Handler初始化的时候直接获取第一个Handler创建的LooperLooper初始化的时候会创建一个消息队列MessageQueue。至此,主线程、消息循环、消息队列之间的关系是1:1:1

Hander持有对UI主线程消息队列MessageQueue和消息循环Looper的引用,子线程可以通过Handler将消息发送到UI线程的消息队列MessageQueue中。

UI主线程通过Looper循环查询消息队列UI_MQ,当发现有消息存在时会将消息从消息队列中取出。首先分析消息,通过消息的参数判断该消息对应的Handler,然后将消息分发到指定的Handler进行处理。

子线程通过HandlerLooperUI主线程通信的流程如图所示。

技术分享

以上摘自百度百科,百科解释得很清晰,故引用。

之所以使用这种机制的原因:(摘自《疯狂Android讲义》)

技术分享

我个人的理解是:

一般我们在使用是通过创建一个新的线程在后台没隔一段时间运行一次,每次给对消息队列发送一个消息,发送的消息是带有参数的,参数表示这个消息是要发送给哪个handler的,然后在主线程里面有个looper的家伙就不断地查询这个消息队列,如果这个消息队列有消息就会把消息去出来,根据消息的参数确定这个消息是要发送给哪个handler的,然后通知对应的handler来处理,如果在handler的处理函数里面有消息对应的处理方法就把消息取走,不然的话就不取走。由于消息队列是按照先进先出的队列原则,所以,如果消息没有被取走的话就会一直堵在那边,这个时候所有的handler将不在执行,所以,在发送消息的一定要确定是要发送给哪个handler和对应的handler里面一定要有相应的处理函数。这里所说的对应是,要有对应的if(msg.what==消息)

还有一个网友总结得挺贴切的一张图:

技术分享

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。