Handler中的Message对象的构造_移动开发_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > 移动开发 > Handler中的Message对象的构造

Handler中的Message对象的构造

 2013/8/10 14:58:11  天朝小浪子  博客园  我要评论(0)
  • 摘要:在用Handler时,我们使用Message对象时,google不推荐我们通过newMessage()来构造一个Message对象,因为Message我们会频繁的使用,不断的new,导致内存碎片,效率不高。Google推荐我们通过obtain()方法构造,为什么了?obtain()内部是怎么实现构造Message从而避免频繁的new而造成的浪费?首先我们看看obtain()函数:1publicstaticMessageobtain(){2synchronized(sPoolSync){3if
  • 标签:Handler 构造

在用Handler时,我们使用Message对象时,google不推荐我们通过new Message()来构造一个Message对象,因为Message我们会频繁的使用,不断的new,导致内存碎片,效率不高。Google推荐我们通过obtain()方法构造,为什么了?obtain()内部是怎么实现构造Message从而避免频繁的new而造成的浪费?

首先我们看看obtain()函数:

 1     public static Message obtain() {
 2         synchronized (sPoolSync) {
 3             if (sPool != null) {
 4                 Message m = sPool;
 5                 sPool = m.next;
 6                 m.next = null;
 7                 sPoolSize--;
 8                 return m;
 9             }
10         }
11         return new Message();
12     }

其他重载的obtain()函数里面都是调用了obtain(),所以只需要搞清楚这一个就成了。

首先判断sPool != null,这儿sPool是Message的一个静态内部对象:

private static Message sPool;

如果我们首次调用sPool肯定是null了,那么该函数也就直接执行 return new Message()了。执行完sPool仍然是null,那么sPool在初始化了,我们看到其在recycle()中初始化。

 1     public void recycle() {
 2         clearForRecycle();
 3 
 4         synchronized (sPoolSync) {
 5             if (sPoolSize < MAX_POOL_SIZE) {
 6                 next = sPool;
 7                 sPool = this;
 8                 sPoolSize++;
 9             }
10         }
11     }

该函数被调用的地方很多,但主要是在Looper.loop()中,这儿实现了回收,开始时sPoolSize小于MAX_POOL_SIZE(该值为10),那么每调用一次recycle(),sPool,next就会被赋值,sPoolSize++,直到sPoolSize = MAX_POOL_SIZE。在这儿sPoolSize++的过程中,sPoll指向调用者对象,保留该对象的引用,next指向前一个对象的引用,注意,这儿next是Message的内部属性成员,不是static的,所以这样下来就形成了一个单向链表,每个节点是调用了recycle()方法的Message对象,该链表的最大长度是MAX_POOL_SIZE。

    我们回过头来再看obtain(),当sPool != null时,m = sPool,其作为返回值,然后给sPool重新赋值:sPool = m.next,然后m.next = null,sPoolSize--。这个操作其实就是删除链表的最后节点并返回的操作。由此可见原先new的Message对象在这儿都给返回重新使用,实现了重复利用。

    Handler中的消息队列其实也就是一个Message对象,也就是说消息对写并不是MessageQueue来维护,而是由Message自己来实现的。

发表评论
用户名: 匿名