Handler源码小窥

来源:互联网 发布:easybcd引导ubuntu 编辑:程序博客网 时间:2024/06/06 11:44
最近在学着看源码,之前看源码,就是点进去直接看,看得很多却毫无收获,而且越看越模糊。受大佬教育启发,看源码一定要带着问题或者目的去看,才不会一团模糊,不懂得自己怎么看了什么。将具体的问题深入到源码中,结合源码进行分析,会印象深刻更有收获

问题:
1.Handler如何发送消息
2.Handler如何切换线程的?(如何使用handler进行线程间通讯?)
3.如何在子线程创建handler?

2.入口:
handler.sendMessage(new Message());进入查看代码
sendMessageAtTime(),里赋值了一个MessageQueue变量
发现未知类型 MessageQueue,进入查看构造方法,消息队列

往消息队列里放入消息,就没有什么触发的代码。
既然有放入消息,就一定有取出的地方,看message压入的代码

Q:如何取出 MessageQueue中的消息?


发现
有一个无限的for循环
是处理消息队列的压入消息的逻辑
发现MessageQueue的mMessages是“队列”的“主链子”容器
需要寻找主链子的提取(相当于提取主链子的“头部”)
得知MessageQueue只是处理Message的链表的逻辑代理类
所以提取动作应该还在MessageQueue寻找?
通常提取动作(肯定remove)
寻找remove关键字,看如何拆除Message关系

mQueue 在何处赋值?mQueue = mLooper.mQueue;
发现未知类型 Looper,进入Looper中查看
在构造方法中看到new 了一个MessageQueue和当前线程mThread
可以得知,Looper类中就是存放MessageQueue和当前线程的一个容器
点进MessageQueue查看




new 一个Thread,在Thread中new一个Handler
直接new 报错
提示子线程在没有调用Loper.prepare()时,不可以new Handler
在new Handler前,增加Loper.prepare()后再云行

使用该handler发送消息,handleMessage没法接收到消息?
在后面加上Looper.loop(),在运行,就可以收到消息
why?
分析过程:
从Loper.prepare()进入,发现未知类型 ThreadLocal
ThreadLocal是一个用线程做key的键值对类
所以通过ThreadLocal就能判断某条线程是否存在某条信息
如果没有某条线程中没有值,则new looper作为值
new Looper中,实例化MessageQueue

Handler的构造方法中,有Looper和MQ建立关系的代码

经分析,Looper的loop()方法是一个无限循环从MQ中取出消息
将msg赋给了Handler
0 0
原创粉丝点击