天天看点

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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