Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android對象池之Message

android對象池之Message

編輯:關於Android編程

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

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

*

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.

上文的意思是: 雖然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加入到對象池的!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved