用了许久的Handler,对于Handler的使用确实是比较熟悉,但是具体内部是如何运作的,却只是模糊的。Handler发出的消息怎么到达MessageQueue?MessageQueue的数据怎么被轮循处理?Looper是怎么循环取MessageQueue的消息的。今天,通过在子线程中创建Looper的实例,以追溯源码的方式来分析这个流程,通过这种方式来理解Android的消息处理机制。
首先,如果我们想在子线程里边实现这个Handler消息处理机制,我们这样处理:
这么简单的几行代码,就能完成一个消息机制,背后肯定是封装了不少的逻辑,还是得学习一下Google大神的编程思路,能把代码简化到这种程度。下面我们跟着代码,一步步展开这个代码的运作过程。
首先,调用Looper的静态方法prepare(),并且将Looper传入ThreadLocal,后边用到。
由此可看到,在此创建了该线程的Looper对象,Looper对象创建时,会创建出MessageQueue!(后边会使用该MessageQueue来轮循及Handler会消Message发送至此)!
紧接着,便是创建Handler,此处使用了刚刚Looper所创建的MessageQueue(可见,handler的创建要后于Looper),这里便完成了MessegeQueue的连通!
顺带地,我们看看handler发送消息时做了些什么。此处调用了enqueueMessage,将消息放入刚刚从Looper获取到的MessageQueue。
继续就是调用了Looper.loop(),通过myLooper获取到Looper.
此处,通过ThreadLocal获取得Looper,前边调用prepare时传入ThreadLocal!
继续查看loop方法!由此可看见一个死循环,这就是Looper能够循环取消息的道理!(当然,子线程也会因为此处不断循环而阻塞于此,暂不运行线程loop以下的方法,直到Looper被调用退出!)
此处loop将从messageQueue取出的消息中Handler,并且调用其dispatchMessage
此时会接着调用应用所实现的handleMessage方法,处理相关的逻辑!
子类必须实现的handleMessage方法!
自此,完成了整个流程的分析,以前看着很绕,现在看看源码,感觉还是蛮清晰的。
小结:Looper创建了消息队列,然后把消息队列传给相应的handler(Looper先于Handler创建),从而实现两者的沟通,然后,looper再不断地从消息队列里取数据,当应用调用该线程的handler,并且发送消息,Looper从队列取出,然后再回调用户实现的handlerMessage方法。因此,线程消息的处理机制,在Android方面,最本质的是Looper,所以创建的handler传入什么线程的Looper,则该handler的数据也同时运行了该线程之下。此时就很好理解,getMainLooper的作用了。
加油,共勉!