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加入到对象池的!
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。