歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> 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

Copyright © Linux教程網 All Rights Reserved