Android Handler机制源码解析
一直想写博客,但是都没有进行,今天这篇handler机制算是开头第一篇吧哈哈。这篇博客不为别的。就算是把自己对于handler机制的理解写下来,也方便以后可以回顾下,如果能够帮到别人就更好了。
Android 规定对于修改界面UI的操作必须放在主线程中执行,而对于一些查询数据库或者联网请求数据的耗时操作,为了避免产生界面暂时无响应等ANR的情况要放到子线程中进行。耗时操作完成后我们要切换到主线程去修改UI,涉及到线程间的通讯,这时候handler机制就派上用场了。
Handler机制的组成部分
Handler机制由四部分组成:Handler,Message,MessageQueue(消息队列),Looper(轮询器)。
Handler:我把他称为消息处理器,handler机制中的重中之重,他与Looper相互协作,通过对MessageQueue进行消息的存取,从而达到线程间的通讯。可以说Handler想要正常的工作就必须有相对应的Looper轮询器,如果新创建Handler所在的线程没有looper对象,则会报错”can’t creat handler inside thread that has not calledLooper.prepare()”,即无法再没有调用Looper.prepare()方法的线程中创建Handler.而这一定在Handler的构造方法中也得以体现。
Looper:轮询器,主要作用是维护MessageQueue,与Handler协作对消息队列进行消息的存取。Looper的实例可以通过Looper.prepare()获得。有一点必须要说明的是Looper本身是线程级别的,这里贴出一段源码可以看出来,sThreadLocal 是ThreadLocal的一个实例,它是一个线程级别的数据存储类,从这里可以看出Looper是线程级别的。
Message:消息,可以通过Message.obtain()方法获得,message.what=..一般用于对该消息的编辑以便在handlerMessage时进行区分,而想要传递给主线程的数据可以通过message.obj=..来进行传递。
MessageQueue:消息队列,为先进先出的线性队列结构,Messagequeue本身是由looper维护的,在这里贴一段Looper构造器源码。
Handler机制的大概流程:
首先大概流程是:子线程耗时操作完毕后,将想要传递给主线程的数据存储到Message对象或者将想要进行的操作封装在Runable的run()方法中,然后通过Handler发送到消息队列MessageQueue中。Loopper通过loop方法对消息队列进行轮询,该方法是个死循环,如果有消息队列中有消息,就将该消息取出发送给发送该消息的handler,进而来处理该消息;如果消息队列中没有消息,则保持堵塞。
源码分析:
首先从发送消息看起,我们知道Handler发送消息既可以sendMessage(Message msg),也可以通过post(Runablerun)来进行,
(1)先来看典型的sendMessage():
可以看到sendMessage()也是调用的sendMessageDelayed(),然后sendMessageDelayed()则调用sendMessageAtTime(),流程很简单不多说。随后走了enqueueMessage()方法,这个方法做了什么呢?
(Handler中的equeueMessage()方法)
(MessageQueue的equeueMessage()方法)
可以看到是调用了MessageQueue的enqueueMessage()方法从而将消息添加到了消息队列中。enqueueMessage()方法中有点需要注意的是在方法的最开始它对msg.target这个对象是否为空进行了判断,如果为空则报错,那么msg.target到底是什么呢?如果刚才你有仔细看Handler中enqueueMessage()方法的话,就会发现msg.target=this,而this即为Handler.这也是为消息打上一个标记,因为在后边的流程中,msg会被传递到它所标记的handler中进行处理。
一切无误,该Message就被加入了MessageQueue消息队里中,这时候我们该看看Looper是怎么从MessageQueue中获取消息然后分发的呢。
这就需要Looper的loop()方法了,可以看出他是个死循环,然后从他所维护的MessageQueue中轮询获取消息,没有消息便保持阻塞状态,有消息则调用msg.target.dispatchMessage()方法,从上面我们知道msg.target其实就是发送该消息的Handler,这时候我们看看dispatchMessage()方法都做了什么。
我们暂且忽略msg.callback和mCallback这个判断,后边我们会提到,这时候则调用了handlerMessage()方法也就是我们在创建Handler对象时重写的handlerMessage()方法。
(2)handler.post(Runable runable)
除了上边说的通过handler的sendMessage()发送消息,我们也可以通过handler.post(runable)来发送个Runable接口对象。
可以看到该方法里边也是调用了sendMessageDelayed()方法,而第一个参数getPostMessage(r)则是将我们post 的Runable对象包装成一个Message对象。
那么上边提到的Handler的dispathMessage()中的msg.callback也就是我们通过handler.post(runable)的runable对象了。而其中的handlerCallBack()无非就是调用runable中的run()方法了。
在上边上边提到的Handler的dispathMessage()中的mCallback其实是我们在创建Handler对象时传入的CallBack接口对象,在Handler的构造方法中可以看到,这里就不再说明了。
第一次写博客,可能描述不清晰,见谅哈哈哈,转载请标明出处哦。