handler的内部实现

handler的内部基本上可以分为四部分

一 Message对象创建  
handler.obtainMessage(),在底层是调用的Message.obtain方法,如果消息池中有Message对象,就直接调用,如果为空,才new Message()进行创建.
消息队列中的顺序是由消息本身维护的,消息队列中的消息是类似单链表的结构,每个消息对象都有一个next属性,指向下一个消息.
假设消息池中有三个消息 a.b.c  进入到obtain的方法中,首先判断sPool(是消息池里的第一条消息) 是否为空. 不为空,就赋值给Message对象, sPool = m.next; 把sPool指向b消息; sPoolSize-- 长度自减   return m ,这时消息队列中的消息就只剩下 b 和 c

二 Handler的创建
在new Handler的时候会直接拿到Looper对象(Looper.myLooper())和消息队列对象(mLooper.mQueue)  Looper对象和消息队列对象都是直接获取的.这两个对象在应用启动的时候就已经创建好了
应用启动的时候,主线程(UI线程)会创建并启动,会调用创建Looper对象和消息队列对象的方法prepareMainLooper()  
Looper可以不停的进行轮训,因为调用了Looper.loop()方法,其内部是一个while(true)的死循环,所有对主线程的更新都是在这个循环中执行的  主线程不会停止就是因为这个Looper类中的loop方法中的while循环   
这里是主线程真正执行的地方

在循环中,不断的读取消息队列中的消息,
管道机制:  在管道中有一个特殊文件,其实就是一个共用内存,它有两个引用,一个读取,一个写入,子线程不断写入,主线程不断读取,完成信息的交互.

如果消息队列中没有数据,主线程会进入睡眠,当子线程写入数据时,主线程苏醒,读取数据, 唤醒主线程的是管道,而不是消息队列中的消息,当子线程往消息队列中写入消息后,还需要往管道中写入一个数据.唤醒主线程

三 消息的发送
消息发送的所有方法最终都回到了sendMessageAtTime(), 把消息插入到消息队列中.放入消息队列中都是依据一个时间参数找到位置的,
如果消息队列是空的,那么肯定是发送的消息肯定是第一条
如果when = 0 或者 when < p.when(第一条消息的时间) 那么这条发送的消息就插入到了第一条
否则,就要那msg.when和消息队列中的每条消息的when进行比较,选择msg的位置.

四 Looper处理消息
Message对象中有一个成员变量target,这个target是记录此消息对象是由谁创建的,
是在obtain方法中传入的this参数赋值的,也就是handler对象
就是说target是有那个handler创建的,那么消息就有那个handler负责处理. 因为可以有多个handler给同一个消息队列发送消息



































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值