Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / Android 线程Message消息分析

话说在工作中第一次接触Android 的Handler 的时候,不知道怎么去关注性能。
 
记得当时这么写的:
 
Message msg = new Message()
msg.what = xxx;
msg.arg1  = xxx;
msg.arg2  = xxx;
handler.sendMessage(msg);
这样写也没有绝得不好,反正当时项目的功能实现了。(性能上还可以)
 
后来没事的时候看了看handler 的其他的方法,就看到了obtainMessage()这个方法.很奇怪,不知道为何还要出来的方法
 
本来上面的那段code 就能实现handler 的功能了,为什么还要出现他,后来百度google 一把,大家说 什么性能上有差别之
 
类的。。。。。结果可想而知。于是我就去看源码能否看到一些好的描述。
Message msg = handler.obtainMessage();
msg.what = xxx;
msg.arg1  = xxx;
msg.arg2  = xxx;
msg.obj    = xxx;.................... 
看看这两段代码其实就是方法不一样 ,参数都一样。但是为何实现的效果一样还要分离出来这么多方法呢?
 
到源码去看个究竟吧!
 
先去看sendMessage()这个方法。。。。它调用的是Handler 中的sendMessage(Message msg)
 
源码 片段1  如下:
 /**   * Pushes a message onto the end of the message queue after all pending messages
 
   * before the current time. It will be received in {@link #handleMessage},
 
   * in the thread attached to this handler.
 
   * 
 
   * @return Returns true if the message was successfully placed in to the
 
   *       message queue.  Returns false on failure, usually because the
 
   *       looper processing the message queue is exiting.
 
   */
 
    publicfinal booleansendMessage(Message msg)    {
 
        returnsendMessageDelayed(msg, 0);
 
    }
  再看handler.obtainMessage()源码 片段2 如下:
 /**    * Returns a new {@link android.os.Message Message} from the global message pool. <BR> * More efficient than creating and allocating new instances. <BR>   * The retrieved message has its handler set to this instance <BR> * (Message.target == this).
 
    * If you don"t want that facility, just call Message.obtain() instead.
 
    */
 
   
 
 
 
 publicfinal Message obtainMessage()
 
 {
 
     returnMessage.obtain(this);
 
 }
 
上面这两段都是Handler 里面的方法,不过在片段1  我们可以看到Message是我们作为参数传过去的,片段2的则是我们
 
Message帮我们处理,它调用obtain(Handler h)方法,之后我们还要调用Message中sendToTarget()这个方法。
 
看一下Message.obtain(Hanlder h) 的源码  代码片段3如下:
/** * Same as {@link #obtain()}, but sets the value for the <em>target</em> member on the Message return * ed.
 
 * @param h  Handler to assign to the returned Message object"s <em>target</em> member.
 
 * @return A Message object from the global pool.
 
 */
 
  publicstatic Message obtain(Handler h) {
 
      Message m = obtain();
 
      m.target = h;
 
 
 
      returnm;  }
 再看 sendToTarget() 源码   代码片段4 如下:
 /** * Sends this Message to the Handler specified by {@link #getTarget}.
 
 * Throws a null pointer exception if this field has not been set.
 
 */
 
  publicvoid sendToTarget() {   target.sendMessage(this);
 
  }
  这里的target就是handler,sendToTarget()又在调用handler的 sendMessage 方法了。。。
 
   看到这里也许有的人很疑惑,这样转来转去,转了一圈怎么又回到Handler的 sendMessage方法了?那么性能比较一说
 
   还有其他的证据么?(难道调用的方法多性能就低么?也许有这么一点原因,不过这里几乎可以不考虑这一点性能损耗的)
 
   那么性能的比较证据应该从哪里找呢? 
 
 
其实细心的同学已经看到了,注意看源码的注释,
 
/**
 * Returns a new {@link android.os.Message Message} from the global message pool. More efficient than
 * creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this).
 * If you don"t want that facility, just call Message.obtain() instead.
 */
 
    这里我们的Message 已经不是 自己创建的了,而是从MessagePool 拿的,省去了创建对象申请内存的开销。。。。。
 
 到这里大家应该都明白了。所以以后使用的时候尽量使用 Message msg = handler.obtainMessage();的形式创
 
 建Message,不要自己New Message 至于message产生之后你使用obtainMessage 或者是 sendMessage 效率影响
 
 并不大.同时我们也要注意以后谈论性能的时候要找准位置,譬如这里性能的问题不是在调用 obtainMessage 和 sen
 
  dMessage 的方法上,而是调用他们之前对象的创建问题上。更多Android相关信息见Android 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=11