handler——消息池

本文解析了Android中Message对象池的工作原理。重点介绍了Message类的obtain()和recycle()方法,解释了如何通过这些方法实现Message对象的复用,以减少内存分配的开销。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自http://blog.youkuaiyun.com/zlp1992/article/details/50295773

先看Message的静态成员方法 Message.obtain();

    // sometimes we store linked lists of these things  
    /*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;  
    /** 
     * Return a new Message instance from the global pool. Allows us to 
     * avoid allocating new objects in many cases. 
     */  
    public static Message obtain() {  
        synchronized (sPoolSync) {  
            if (sPool != null) {  
                Message m = sPool;  
                sPool = m.next;  
                m.next = null;  
                sPoolSize--;  
                return m;  
            }  
        }  
        return new Message();  
    }  


在这个类中sPool代表这个消息池的头消息,sPoolSize表示消息池中可用的消息的个数即没有被使用的Message对象的个数,next表示下一个可用的消息Message对象。
可以看到obtain()方法说会从全局消息池中取消息,假设是第一次获得一个Message对象,那么sPool肯定为null,也就说第一次获取消息Message对象时是还没有消息池的,必须通过Message的构造方法获取一个Message对象的,Message的构造方法什么也没干

    /** Constructor (but the preferred way to get a Message is to call {@link #obtain() Message.obtain()}). 
    */  
    public Message() {  
    }  


那这就有点奇怪了,它的消息池是什么时候初始化呢?难道不是先new几个Message对象然后存着?这是我们注意到Message类的另一个成员方法recycle(),注意这个方法不是静态的

    /** 
     * Return a Message instance to the global pool.  You MUST NOT touch 
     * the Message after calling this function -- it has effectively been 
     * freed. 
     */  
    public void recycle() {  
        clearForRecycle();  
      
        synchronized (sPoolSync) {  
            if (sPoolSize < MAX_POOL_SIZE) {  
                next = sPool;  
                sPool = this;  
                sPoolSize++;  
            }  
        }  
    }  

里面的clearForRecycle()方法只是把一些成员变量置为null,以便垃圾回收

    /*package*/ void clearForRecycle() {  
        flags = 0;  
        what = 0;  
        arg1 = 0;  
        arg2 = 0;  
        obj = null;  
        replyTo = null;  
        when = 0;  
        target = null;  
        callback = null;  
        data = null;  
    }  

从这里我们就可以发现,消息池中Message的对象是通过recycle()放进去的. 但是我们自己并没有调用recycle()方法,那这个方法是在哪里调用的?看下Looper的源码就知道,在Looper的loop()方法的最后调用了Message对象msg的recycle()方法来回收这个Message对象,通过recycle()将这个Message对象的数据清空然后链接到消息池中(采用的头插法)。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值