android對象池之Message

來源:互聯網
上載者:User

標籤:android開發   對象   線程   鏈表   

        在android系統中,message常在多線程之間資訊交流中用到,通過Handler來傳遞線程間的訊息(message).今天討論的是android中的message特性:對象池.

        在android中,google對message有一句這樣的英文說明:

       * <p class="note">While the constructor of Message is public, the best way to get
       * one of these is to call {@link #obtain Message.obtain()} or one of the
       * {@link Handler#obtainMessage Handler.obtainMessage()} methods, which will pull
       * them from a pool of recycled objects.</p>

       上文的意思是: 雖然message的構造方法是對外開放的(public),但是,我們要擷取一個message時候最好使用這個方法obtainMessage(),這個方法可以從一個可以複用的對象池中擷取你需要的message.

      同上面的意思,我們可以知道,原來message內其實維護了一個對象池,當我們使用完一個message的時候,這個message很有可能就會儲存在這個對象池裡面,也就是說message裡面有一個對象池來儲存我們使用過的message.實際上,通過代碼,我們可以知道當對象池裡面沒有我們需要的message時候,會自動new 一個message的. 所以不必擔心obtainMessage()擷取不了message.

     現在來看看android的message的對象池時如何設計的.實際上,message裡面的對象池其實是通過維護一個單項鏈表來實現的!看看下面就知道來.

     在message裡面有一下幾個變數的聲明和定義:

    /*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;
      next 指向下一個可用的message;      

      sPoolSync主要用來同步用的,保證多安全執行緒;

      Message sPool;這裡的sPool用來表示當前一個可用的message,請注意這是一個static修飾的message,

     sPoolSize用來記錄當前message對象池有多少個messagel . 

     最後解釋一下: message裡面其即時維護來一個單項鏈表結構來儲存message對象的!next永來指向下一個message對象,這裡的sPool很顯然就是這個鏈表的表頭.這樣以來就可以通過表頭順序遍曆整個對象池裡面的message.

    上面我說了,當通過這個方法obtainMessage()來擷取一個message時候,就會去對象池裡面找取(這裡就是去這個單向鏈表中找取),如果對象池裡面沒有我們需要的message,就會new一個message. 我們來看看代碼來證明我所說的.

    public static Message obtain() {        synchronized (sPoolSync) {            if (sPool != null) {                Message m = sPool;                sPool = m.next;                m.next = null;                sPoolSize--;                return m;            }        }        return new Message();    }
      通過上面的代碼可以看出:如果鏈表不為null,就取鏈表頭的message,然後把鏈表頭部下移動. 否在就會new Message().

      最後要說的是,當一個message用完了後是如何加入這個鏈表的呢? 通過檔案Message.java,你會發現在Message裡面還定義來一個public的方法:

    public void recycle() {        clearForRecycle();        synchronized (sPoolSync) {            if (sPoolSize < MAX_POOL_SIZE) {                next = sPool;                sPool = this;                sPoolSize++;            }        }    }
      通過上面的代碼可以知道recycle方法其實就是將這個message加入到這個鏈表(加入到了頭部).那麼,這個方法時在何時調用的呢?

      實際上,當通過Handler發送一個message的時候,其實是將這個message根據他的延時來決定他的位置,將其添加到一個隊列裡面的MessageQueue,操作這個MessageQueue不僅僅是這個Handler,還有這個Handler的Looper.

     其實每一個Handler都是需要一個Looper的,往往我們建立一個Handler的時候其實是沒有指明他的Looper,不過他會自動擷取建立這個Handler的線程的Looper來作為自己的Looper,所以,在android中,往往沒有指明Handler的Looper,其實就是用主線程(就是我們常說的ui線程)的Looper.

    剛才我們說了,Handler的Looper其實也操作MessageQueue的,實際上一個Looper就需要一個MessageQueue的,我個人的理解是:Looper的目的就是操作MessageQueue,而Handler控制著Looper和MessageQueue.

   其即時這樣的: Handler往MessageQueue裡面加入需要處理的message,而Looper從MessageQueue裡面取出需要處理的message來開始處理流程.

   在Looper裡面其實是通過調用方法loop()來取出需要處理的message,並處理,處理完畢時候就會調用這個message的recycle(),由此來將處理完畢的message加入到對象池的!

android對象池之Message

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.