Android的Handler、MessageQueue、Runnable和Looper的联系(源码选自21版本)
来源:互联网 发布:2016 mac pro强制重启 编辑:程序博客网 时间:2024/05/18 02:30
原文地址:http://blog.csdn.net/AA747604141/article/details/47282049
Android的Handler、MessageQueue、Runnable和Looper的联系(源码选自21版本)
写过一段时间Android代码的程序猿朋友们可能都知道:Looper是一个循环,维护一个消息队列MessageQueue,Handler是一些事件,循环的放入队里中事件然后去处理和回调,但也许还没来得及看一看源码,这块是咋工作的,我这里小做整理,以防以后忘记了,回过来再回味一下【高手欢迎批评指正~】。
在这里,通过下面的分析,我想要回答三个问题:
1.他们四个是怎么联系在一起的?
2.我们在用Handler的时候,一直在脑海中的原理如何从源码级别体会到的呢?
3.应用在运行的时候,它是咋开启的呢?
通过Looper源码的分析,可以找到Handler、MessageQueue和Looper的联系。Looper.java的doc文档也大概介绍了Handler的工作机制,咋一读可能品味不到什么,但捋一遍源码再回头看,其实说的很明白,即:
- class LooperThread extends Thread {
- public Handler mHandler;
- public void run() {
- Looper.prepare();
- mHandler = new Handler() {
- public void handleMessage(Message msg) {
- }
- };
- Looper.loop();
- }
- }
从头说起,当我们new一个Handler的时候,即Handler mHandler = new Handler();跟踪Handler.java类,可以看到,它访问了Handler(null, false)方法。这里面传入了Looper,即mLooper = Looper.myLooper()【mLooper肯定不会为null了,否则Handler肯定会创建失败的,这个后面提】;将Looper的MessageQueue传递到了Handler。那么,可以看到了,Looper内一定维护了一个队列了。
我们可能会调用mHandler的post(Runnable)方法,这样就可以执行一段我们想要的操作(当然,也可以使用sendMessage的方式,这个到底有什么区别?)。跟踪post这个方法可以看到,它是将Runnable装换成了Message,同时将runnable传递给Message的callaback参数。它访问了enqueueMessage(),这个Message入队了。
消息入队了,那么它是怎么执行的呢?这个问题由Looper.java来回答。回到Handler的构造函数,它调用了myLooper(),查看这个方法,它是从ThreadLocal里面取了一个Looper。为什么ThreadLocal.get()肯定不会为空呢?首先,可以看看最上面那段LooperThread 的代码,它说:在我们new Handler之前,肯定是系统已经调用了prepare()方法装填了一个Looper了。那究竟这段代码是怎么调用的呢?这个问题就要到ActivityThread.java(附录I、II)这个类里面可以看到。原来,在应用进程的主线程在创建的时候,它就调用了prepare()方法了嘛,代码如下(问题三在这里):
Looper.prepareMainLooper(); ... Looper.loop();
所以,在我们new Hanlder之前,肯定ThreadLocal内已经非空了。看到了,这里调用了loop()方法。查看这个方法,我们可以找到一些信息:
1)取出消息队列中的消息:
Message msg = queue.next();
2)执行我们想要的操作:
msg.target.dispatchMessage(msg);
这里,target就是我们的Handler(这个怎么弄的,可以看obtainMessage())。串联起来了吧, 一般我们就是通过dispatchMessage()来执行我们想要的操作的,对吧。
3)这里有个一直在的循环,循环着处理着消息队列中的操作。
应该还有一个问题,我最开始是使用post来执行一段操作的,虽然说过了将它转换成了Message,但并没有重写dispatchMessage,那么传入到Message的Runnable是咋工作的呢,看一下handler的dispatchMessage,一目了然,使用post的调用方式callback 非空,通过handleCallback访问了message.callback.run();而通过sendMessage的方式callback 可能为空,自然就会走handleMessage()了【代码中还有一点细节,mCallback 也非空的情况,不提了】。
- public void dispatchMessage(Message msg) {
- if (msg.callback != null) {
- handleCallback(msg);
- } else {
- if (mCallback != null) {
- if (mCallback.handleMessage(msg)) {
- return;
- }
- }
- handleMessage(msg);
- }
- }
最后再总结一下,Looper内维护一个循环,当应用ActivityThread第一次访问的时候,开启这个循环,随后,通过Handler将Message(sendMessage或者post传入的由Runnable构建的Message)放入Looper内的MessageQueue。
我感觉差不多说清楚了,暂时我是对Android的消息机制这段比以前认识更多了,还有啥我没说清楚的,可以继续一起研究。不得不提一下,强烈推荐一本书《深入理解Android内核设计思想》,其实可以看到,我的很多认识也是从这本书学到的,不能忘记挖井人!
附录:
[1] ActivityThread简介:http://blog.csdn.net/myarrow/article/details/14223493
[2] Acitvity源码:http://code.taobao.org/svn/cnAndroidSDK/trunk/dev/java/android/app/ActivityThread.java
[3] ThreadLocal:http://blog.csdn.net/aa747604141/article/details/17610269
[4] 《深入理解Android内核设计思想》.林学森
- Android的Handler、MessageQueue、Runnable和Looper的联系(源码选自21版本)
- Android的Handler、MessageQueue、Runnable和Looper的联系(源码选自21版本)
- Handler、MessageQueue、Runnable与Looper的源码浅析
- Message MessageQueue Runnable Looper 和Handler的关系理解
- Handler Message MessageQueue Looper 之间的联系
- Handler,MessageQueue,Runnable,Looper
- Android 消息机制 - Handler, Looper, Message, MessageQueue 的源码分析
- 从源码的角度解析Handler、Looper、Message和MessageQueue
- Android-Handler 总结(Handler 的使用 ,Looper , MessageQueue , HandlerThread )
- Android-Handler 总结(Handler 的使用 ,Looper , MessageQueue , HandlerThread )
- Android应用开发多线程基础之Handler,Looper,Message,MessageQueue,Runnable之间的关系
- Android中的Handler, Looper, MessageQueue和Thread的关系
- Android中的Handler、Looper和MessageQueue的使用以及原理
- 浅浅的介绍一下android里面Handler、Looper、Message和MessageQueue是怎么联系到一起的.
- android MessageQueue,Looper和Handler(转载)
- Android中Looper, Handler, MessageQueue的理解
- Android中的Looper,MessageQueue,Handler的理解
- Android--Handler,Looper,MessageQueue的关系
- 单词首字母大写,删除多余空格
- (转载)Deep Learning(深度学习)学习笔记整理系列之(七)
- Sorts Colors
- MySQL索引及优化
- 郁闷的gxg
- Android的Handler、MessageQueue、Runnable和Looper的联系(源码选自21版本)
- 路径规划算法初探
- Java Web SSH-Spring Hibernate Struts SSH三大框架整合概述
- (转载)Deep Learning(深度学习)学习笔记整理系列之(八)
- Android官方文档翻译 二 1.Building Your First App
- 正则表达式一
- 建造者模式Builder Pattern
- Norton Internet Security 序列号提取(卡饭)
- 自定义view