Android消息处理机制之二:消息中obtain源代码剖析

Message中obtain()源码分析

参考自 AHuier的Android消息处理机制之二:消息中obtain()源代码剖析

obtain的源码,可见是从消息池中取出对象。这里为了防止多个任务访问消息池获取对象,使用 synchronized(sPoolSync) 将 obtain() 方法上锁了。

private static final Object sPoolSync = new Object();  
private static Message sPool;  
private static int sPoolSize = 0;  

private static final int MAX_POOL_SIZE = 10;  

/** 
 * 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();  
}  

1) 通过 Message.obtain()方式获取Message对象

public class MyThread implements Runnable{  

    @Override  
    public void run() {  
        // 使用第一种构造方法  
        Message message = Message.obtain();  
        message.what = 1;  
        message.arg1 = 1;  
        message.arg2 = 3;  
        message.obj = "SmartNi";  
        handler.sendMessage(message);  
    }          
}  

2) 通过 Message.obtain(Handler h)的方式获取Message对象

首先查看一下obtain(Handler h)的源码,可见 message 的目标对象已经指向了 Handler ,那么在发送消息的时候就直接调用 sendToTarget() 方法即可。

     /**
     * Same as {@link #obtain()}, but sets the value for the <em>target</em> member on the Message returned.
     * @param h  Handler to assign to the returned Message object's <em>target</em> member.
     * @return A Message object from the global pool.
     */
    public static Message obtain(Handler h) {
        Message m = obtain();
        m.target = h;
        return m;
    }
/* 
 *  第二种获取Message对象的方法 
 *  public static Message obtain (Handler h) 
 *  传递一个关联到消息Handler. 
 */  
Message message = Message.obtain(handler);  
message.what = 1;  
message.arg1 = 1;  
message.arg2 = 3;  
message.obj = "SmartNi";  
message.sendToTarget(); // 完成发送消息的动作  

因为

...  
/*package*/ Handler target;    
...   
/** 
 * Sends this Message to the Handler specified by {@link #getTarget}. 
 * Throws a null pointer exception if this field has not been set. 
 */  
public void sendToTarget() {  
    target.sendMessage(this);  //这里
}  

3) 通过 Message.obtain(Handler h,int what)的方式获取Message对象

/** 
 * Same as {@link #obtain()}, but sets the values for both <em>target</em> and 
 * <em>what</em> members on the Message. 
 * @param h  Value to assign to the <em>target</em> member. 
 * @param what  Value to assign to the <em>what</em> member. 
 * @return A Message object from the global pool. 
 */  
public static Message obtain(Handler h, int what) {  
    Message m = obtain();  
    m.target = h;  
    m.what = what;  

    return m;  
}  

4) 通过 Message.obtain(Handler h, int what, int arg1, int arg2, Object obj)的方式获取Message对象

/* 
 * public static Message obtain (Handler h, int what, int arg1, int arg2, Object obj) 
 * 关联Handler和传递Message的几种常用属性值 
 */  
Message message = Message.obtain(handler, 1, 1, 3, "SmartNi");  
message.sendToTarget(); 
/** 
 * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>,  
 * <em>arg1</em>, <em>arg2</em>, and <em>obj</em> members. 
 *  
 * @param h  The <em>target</em> value to set. 
 * @param what  The <em>what</em> value to set. 
 * @param arg1  The <em>arg1</em> value to set. 
 * @param arg2  The <em>arg2</em> value to set. 
 * @param obj  The <em>obj</em> value to set. 
 * @return  A Message object from the global pool. 
 */  
public static Message obtain(Handler h, int what,   
        int arg1, int arg2, Object obj) {  
    Message m = obtain();  
    m.target = h;  
    m.what = what;  
    m.arg1 = arg1;  
    m.arg2 = arg2;  
    m.obj = obj;  

    return m;  
}  

5) 通过上述几个例子我们可以知道Message中的obtain()的几种重载方法在底层的实现都是大同小异的,他们都是底层都是首先调用obtain()方法来从消息池中获得一个消息的对象的。然后在通过参数传递来封装指定的Handler和需要携带的数据。如果使用这些重载的方法建议完成数据封装之后调用sendToTarget()方法。这就是几种obtain()重载方法的不同。

6) 这里我们需要特别注意Message中的这个重载方法:Message obtain (Message orig) 它是将原有的消息体作为一个新的消息参数来发送的,我们看一下它的源代码。

/** 
 * Same as {@link #obtain()}, but copies the values of an existing 
 * message (including its target) into the new one. 
 * @param orig Original message to copy. 
 * @return A Message object from the global pool. 
 */  
public static Message obtain(Message orig) {  
    Message m = obtain();  
    m.what = orig.what;  
    m.arg1 = orig.arg1;  
    m.arg2 = orig.arg2;  
    m.obj = orig.obj;  
    m.replyTo = orig.replyTo;  
    if (orig.data != null) {  
        m.data = new Bundle(orig.data);  
    }  
    m.target = orig.target;  
    m.callback = orig.callback;  

    return m;  
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值