前言
Handler常见子线程更新UI的问题。Handler是一种生产者和消费者模型,Handler作为生产者,将消息发送到MessageQueue(由链表完成),Looper作为消费者,不断地从MessageQueue中拉取新的消息。Looper本身并不对消息做处理,Looper代表了消息的目标线程,拉取消息后分发到对应的Handler(发送消息的Handler)去处理,这个过程实现了跨线程处理。
Looper
让普通线程能够使用Handler机制处理消息,必须先调用Looper.prepare(),再调用Looper.loop()。preapare是利用ThreadLocal在调用的线程中构造唯一的Looper。Looper构造函数里会创建一个新的MessageQueue。一个Looper对应一个MessageQueue,一个线程只有一个Looper,只有一个MessageQueue。
Handler
Handler构造可以指定Looper并保存到mLooper中,代表使用这个Handler发送的消息,能够在指定的Looper线程中处理。
一个Handler 对应一个Looper,多个Handler可以用同一个looper进行初始化。一个looper对应多个Handler,一个线程也可以有多个Handler。
可以有多个生产者(Handler),多个生产者可以向同一个MessageQueue发送消息。由于MessageQueue是随Looper创建而创建,和Looper一一对应,Handler机制通过ThreadLocal限制一个线程仅能有一个Looper,因此一个MessageQuque也仅有一个Looper消费消息。
Looper作为消费者并不处理消息,分发到Handler去处理
Handler发送消息后的流程
Handler可以通过post、sendMessage等函数发送消息,最终调用sendMessageAtTime函数,则是调用enqueueMessage向Handler对应的队列插入消息。Handler的enqueueMesage函数,将自身引用保存到msg.target(Handler),为以后消息分发。最终调用MessageQueue的enqueueMessage函数
消息插入MessageQueue
MessageQueue使用链表实现的。根据目标时间插入到MessageQueue中正确的位置。Handler发送消息后就是根据消息目标的执时间,插入到MessageQueue中。
Looper处理消息的流程
线程使用Looper必须调用Looper.prepare(),再调用Looper.loop()。loop函数是用来循环从MessageQueue中取出消息。loop()函数中主要是循环调用loopOnce直到返回false,loopeOnce函数通过MessageQueue的next函数获取消息,再分发出去。next函数中,获取当前的upTime,消息队列消息经过遍历,早于当前时间的消息被从链表中取出,时间未到的进入休眠等待唤醒。
消息的分发和处理
loopOnce函数中,获取的消息会调用msg.target.dispatchMessage(msg),消息入队时,Handler将自身引用保存到消息的target中,再消息存在的callback时调用handlerCallback,否则看Handler创建时是否指定Callback,均没有则调用handlerMessage进行处理。消息的处理通常实现一个Handler子类并重写handlerMessage函数,或者实现callback接口。