Android Handler 机制实现原理分析
handler在安卓开发中是必须掌握的技术,但是很多人都是停留在使用阶段。使用起来很简单,就两个步骤,在主线程重写handler的handlemessage( )方法,在工作线程发送消息。但是,有没有人想过这种技术是怎么实现的呢?下面我们一起探讨下。
先上图,让大家好理解下handler机制:
handler机制示例图
上面一共出现了几种类,activitythread,handler,messagequeue,looper,msg(message),对这些类作简要介绍:
activitythread:程序的启动入口,为什么要介绍这个类,是因为该类就是我们说的主线程,它对looper进行操作的。
handler:字面意思是操控者,该类有比较重要的地方,就是通过handler来发送消息(sendmessage)到messagequeue和 操作控件的更新(handlemessage)。handler下面持有这messagequeue和looper的对象。
messagequeue:字面意思是消息队列,就是封装message类。对message进行插入和取出操作。
message:这个类是封装消息体并被发送到messagequeue中的,给类是通过链表实现的,其好处方便messagequeue的插入和取出操作。还有一些字段是(int what,object obj,int arg1,int arg2)。what是用户定义的消息和代码,以便接收者(handler)知道这个是关于什么的。obj是用来传输任意对象的,arg1和arg2是用来传递一些简单的整数类型的。
下面,我们按照启动顺序来进行源码分析:
从上面可以看出,activitythread类是用来启动android的,其源码为:
activitythread类:
接下来,我们看到looper类了,我们进去看看里面的源码实现:
首先,我们看看里面有哪些字段:
looper的内部属性
然后我们迫不及待地要想去看看preparemainlooper方法,到底干了什么
looper.preparemainlooper()方法
这里我们可以看到,preparemainlooper是为了设置一个持有消息队列和消息序列器的looper进去threadlocal。接下来我们看看loop方法吧:
looper.loop()方法
我们可以看到loop方法中,会取出内部的消息序列器,并且迭代里面的消息,根据消息的target分发消息(到handlemessage方法中)。如果你有疑问,你应该是不清楚looper的messagequeue为什么会有message。那么我们就马上去看,到底是哪里添加消息的。话说,到了这里我也好像没有分析到和我们handler相关的操作吧。因为你和我都知道handler的作用是sendmessage和handlemessage,所以我们知道,looper中的消息序列器的消息体,肯定是从sendmessage中添加进去的。不墨迹,我们马上进入handler的源码分析。
首先,我们先看看handler的字段:
handler的字段
接着,我们看看handler的构造方法,我们可以看到,handler有两类构造方法(别看到6个,它们都是往这两种方法调用的):
handler的构造方法
接着,我们要进入handler.dispatchmessage()方法,因为我们要解释上面刚刚looper.loop方法。dispatchmessage的方法很简单,只有三个方向,其源码为:
handler.dispatchmessage()方法
到这里为止,执行代码就结束了。那么问题来了,消息从哪里来的?带着这个疑问,我们马上进入handler.sendmessage()逻辑去看看,其源码是:
handler.sendmessage()方法
好不容易找到了发送消息的逻辑并理解了,但是还要去壳,在messagequeue中分析了,首先,我们回顾下,消息序列器是在looper.prepare()中初始化的。messagequeue源码,构造方法很简单:
messagequeue构造方法
然后我们再到达messagequeue.enqueuemessage()方法中看源码:
messagequeue.enqueuemessage()方法
这个是发送消息的最终执行代码,就是把消息放进消息序列器。在looper.loop()方法中,我们是需要不断从消息序列器中取出消息的。其过程也是我们可以进去messagequeue.next()的源码中看看:
messagequeue.next()方法
这样,整个过程就完成了。在这些执行过程中,message是它们的物件。我们可以看看message的结构:
message的字段
除此之外,message的数据结构是基于链表的,方法都很简单的,我就不贴出来了。
总结一下,其实就是用一个threadlocal来存储对象,然后在执行的时候,能够保证对象的不变形,这样就能达到在主先线程更新ui了。
以上就是对android handler 进行的详解,后续继续整理相关资料,谢谢大家对本站的支持!
下一篇: ASP.NET网页显示LED字体的方法