Handler是Android中用于处理线程中消息循环的机制,在一般的使用中,我们总是以Message作为消息载体,通过Handler发送处理消息,但是只是用还不够,我们还得知道它具体是怎么实现的,因此本文梳理了一下消息循环流程中Handler的具体实现。

1、主角介绍

①Handler:发送消息、回调处理消息

②MessageQueue:按顺序存储消息

③Looper:从消息队列取出消息通知Handler处理

④Message:存储消息

2、一般用法

3、流程概要


首先,我们把这个流程比作寄快递,Handler作为一个普通人,现在他要在北京Thread1处理业务,但是必须要在上海Thread2将东西送过来后才开始,所以它在上海Thread2将快递Message送到sendMessage()快递仓库MessageQueue,这个时候假如快递公司Looper里没有处理这条线路业务的小组,就开始组建prepare()专门送这条线路的业务小组,组建完成后开始让员工从仓库按顺序取件next(),并开始发快递loop(),当快递送到北京Thread1时Handler手中开始处理快递业务handleMessage()。

4、源码分析

(1)Handler

在Handler中一共提供了7个send方法,从图中可以看到无论是哪一个send方法最终都会去到enqueueMessage方法中,这个方法将message与当前Handler绑定,并且将message传递给了MessageQueue。

在Handler中还提供了5个post方法,但是这5个post方法最终走的都是send方法

(2)MessageQueue

在这个类中有两个比较重要的方法,一个是上面所说的enqueueMessage方法,它用于将一个Message放入到消息队列MessageQueue中,另一个是next方法它用于从消息队列MessageQueue中阻塞式地取出一个Message。

(3)Looper

快递Message已经存储了,那现在就需要将它送出去。

首先,看到Looper的构造方法,它是私有的,那就不能从外部就实例化Looper,那么我们什么时候实例化Looper呢,想想我们的是如何使用Looper的,没错就是prepare时。

在实例化Looper时创建了一个新的消息队列用来存储信息,在prepare时会判断当前线程时候已经拥有一个Looper,如果有将不能将实例化好的Looper加入sThreadLocal中,这就保证了一个线程只能拥有一个Looper,那这个sThreadLocal是什么呢

sThreadLocal它是一个Looper的集合而已,并且在ThreadLocal中我们可以看到,set方法在保存值的时候会将当前线程作为键将Looper作为值保存起来。

快递小组组建完成,接下来就要开始干活了。

我们在Looper中loop方法里需要注意的有三个地方,第一的地方说明了这是一个无限循环,这也就说明只要开启了loop,那么它就会一直从消息队列中取出消息即第二个地方,最后一个地方就是通知Handler进行回调的方法了,我们在上面有说过在Handler发送消息时绑定了Handler,这个target就是该Handler。