android对象池之Message

在android系统中,message常在多线程之间信息交流中用到,通过Handler来传递线程间的消息(message).今天讨论的是android中的message特性:对象池.

在android中,google对message有一句这样的英文说明:

* <p class="note">While the constructor of Message is public, the best way to get * one of these is to call {@link #obtain Message.obtain()} or one of the * {@link Handler#obtainMessage Handler.obtainMessage()} methods, which will pull * them from a pool of recycled objects.</p>

上文的意思是: 虽然message的构造方法是对外开放的(public),但是,我们要获取一个message时候最好使用这个方法obtainMessage(),这个方法可以从一个可以复用的对象池中获取你需要的message.

同上面的意思,我们可以知道,原来message内其实维护了一个对象池,当我们使用完一个message的时候,这个message很有可能就会保存在这个对象池里面,也就是说message里面有一个对象池来保存我们使用过的message.实际上,通过代码,我们可以知道当对象池里面没有我们需要的message时候,会自动new 一个message的. 所以不必担心obtainMessage()获取不了message.

现在来看看android的message的对象池时如何设计的.实际上,message里面的对象池其实是通过维护一个单项链表来实现的!看看下面就知道来.

在message里面有一下几个变量的声明和定义:

/*package*/ Message next;private static final Object sPoolSync = new Object();private static Message sPool;private static int sPoolSize = 0;private static final int MAX_POOL_SIZE = 50; next 指向下一个可用的message;

sPoolSync主要用来同步用的,保证多线程安全;

Message sPool;这里的sPool用来表示当前一个可用的message,请注意这是一个static修饰的message,

sPoolSize用来记录当前message对象池有多少个messagel .

最后解释一下: message里面其实时维护来一个单项链表结构来保存message对象的!next永来指向下一个message对象,这里的sPool很显然就是这个链表的表头.这样以来就可以通过表头顺序遍历整个对象池里面的message.

上面我说了,当通过这个方法obtainMessage()来获取一个message时候,就会去对象池里面找取(这里就是去这个单向链表中找取),如果对象池里面没有我们需要的message,就会new一个message. 我们来看看代码来证明我所说的.

public static Message obtain() {synchronized (sPoolSync) {if (sPool != null) {Message m = sPool;sPool = m.next;m.next = null;sPoolSize–;return m;}}return new Message();} 通过上面的代码可以看出:如果链表不为null,就取链表头的message,然后把链表头部下移动. 否在就会new Message().

最后要说的是,当一个message用完了后是如何加入这个链表的呢? 通过文件Message.java,你会发现在Message里面还定义来一个public的方法:

public void recycle() {clearForRecycle();synchronized (sPoolSync) {if (sPoolSize < MAX_POOL_SIZE) {next = sPool;sPool = this;sPoolSize++;}}} 通过上面的代码可以知道recycle方法其实就是将这个message加入到这个链表(加入到了头部).那么,这个方法时在何时调用的呢?

实际上,当通过Handler发送一个message的时候,其实是将这个message根据他的延时来决定他的位置,将其添加到一个队列里面的MessageQueue,操作这个MessageQueue不仅仅是这个Handler,还有这个Handler的Looper.

其实每一个Handler都是需要一个Looper的,往往我们创建一个Handler的时候其实是没有指明他的Looper,不过他会自动获取创建这个Handler的线程的Looper来作为自己的Looper,所以,在android中,往往没有指明Handler的Looper,其实就是用主线程(就是我们常说的ui线程)的Looper.

刚才我们说了,Handler的Looper其实也操作MessageQueue的,实际上一个Looper就需要一个MessageQueue的,我个人的理解是:Looper的目的就是操作MessageQueue,而Handler控制着Looper和MessageQueue.

其实时这样的: Handler往MessageQueue里面加入需要处理的message,而Looper从MessageQueue里面取出需要处理的message来开始处理流程.

在Looper里面其实是通过调用方法loop()来取出需要处理的message,并处理,处理完毕时候就会调用这个message的recycle(),由此来将处理完毕的message加入到对象池的!

,请让我们从容面对这离别之后的离别。

android对象池之Message

相关文章:

你感兴趣的文章:

标签云: