編輯:關於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加入到對象池的!
hybrid app編輯 Hybrid App(混合模式移動應用)是指介於web-app、native-app這兩者之間的app,兼具“Native App良
我們使用社交軟件的過程中多多少少會為別人的帖子點贊,如圖 : 可以看到用戶頁面顯示出來的只是點了贊的用戶的名稱,點擊這些名稱可以進入到該用戶的主頁。我們就
Android studio 圖片錯誤 9-patch image error in AndroidERROR: 9-patch image xx .9.png malf
以前如果要做 Tab 分頁的話,必須要用一個很難用的 TabActivity,而且做出來的效果很差,彈性也很小忘了從什麼時候開始,Google release 了 Vie