Android源码分析----------Handler消息机制(1)Handler获取Message对象及Message的复用

在研究源码之前,我们对Handler的了解一般是这样的概念:

在主线程中,有消息队列Looper,里面有很多的消息,还有一个Handler,用来向Looper发送消息,Looper会将消息接收,不停的取出新消息,并把消息分配给Handler执行,同时,Handler从回收的消息队列中(Message.obtain())获取消息进行复用,再发出新消息,这就构成了Handler的消息机制.

现在,我们就来深入分析一下这里面的具体实现过程.

一.Handler获取Message对象及Message的复用

在Handler的源码中,我们可以发现, Handler.obtainMessage() 方法的返回值,其实就是Message.obtain(),只不过每个方法的返回参数不同.


所以,在复用消息对象的时候,使用Handler.obtainMessage() 方法和Message.obtain()方法其实是相同的.而Message.obtain()的方法,都依赖空参的obtain()方法来生成数据,


所以,我们只需要研究空参的obtain方法即可.

 

通过查看源码可知,空参的obtain()涉及静态变量Message对象 mPool和非静态的Message 对象next.说明每个消息对象都有next属性,而mPool是所有子类共用的.

然后,我们再看Message类中的recycle()方法,也就是用来回收的方法:


recycle()方法里面做了一个判断,如果mPoolSize<MAX_POOL_SIZE,就调用clearForRecycle()方法,把当前的消息对象的所有参数全部清空,可以说,当消息回收的时候,消息对象就被还原成了刚创建时的状态.

所以,消息回收时都做了什么呢?我们画图分析一下:

每个msg对象都有一个next属性,而所有的msg对象共用一个mPool属性,这个前面我们已经说过.一开始的mPool值为null,recycle方法调用时,让next=mPool,而mPool=this,把mPool指向了当前的msg对象,


这时如果再回收一个msg对象,新的msg对象的next属性就指向了mPool,也就是上一个msg对象,而mPool指向了当前的msg对象.以此类推,就形成了回收的消息队列.



接着我们再回到Message的obtain方法:


obtain方法判断mPool是否为空,不为空的情况下,设置一个局部变量m,把m指向mPool也就是最新的对象


mPool指向了m的next对象,也就是上一个msg对象:


接下来将m.next赋值为null,断开了与后面的msg对象的联系:


然后把m给return回去,于是一条干净的msg就被提供给Handler进行复用了.消息队列变成了:


接下来,再判断mPool是否为空,仍不为空的话继续重复上面的操作.直至mPool为空时,创建一条新的消息.

也就是说,Handler在通过Message.obtain()获取消息时,如果有消息,就复用,没有的话,就new一条新消息.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值