編輯:關於Android編程
在obtain的所有重載方法中,第一行都是Message m = obtain();
,即調用空參的方法。
先來看一下這個空參方法
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
很明顯,這是個同步方法,sPoolSync
即鎖對象,該對象在定義時即被初始化private static final Object sPoolSync = new Object();
,隨後便只讀不寫。
然後便是sPool
,後面還有Message m = sPool;sPool = m.next;
,很明顯可以看出來,這是一個鏈表結構。sPool
指向當前message,next
指向下一個message。
在解釋這段代碼前,需要先明確兩點:sPool
聲明為private static Message sPool;
;next
聲明為/*package*/ Message next;
。即前者為該類所有示例共享,後者則每個實例都有。
現在為了便於理解,我們將Message
抽象為C語言中的鏈表節點結構體,指針域便是用於指向下一個消息的next
字段,其他則都視為數據域。
假設該鏈表初始狀態如下
執行Message m = sPool;
就變成下圖
繼續sPool = m.next;
然後m.next = null;
接下來m.flags=0;sPoolSize--;return m;
便是表示m指向的對象已經從鏈表中取出並返回了。
然後再看看sPoolSize
是什麼時候自增的。按圖索骥便可找到recycle()
方法和recycleUnchecked()
方法。前者供開發者調用進行回收,後者執行回收操作。來看看回收操作都干了啥:
void recycleUnchecked() {
// Mark the message as in use while it remains in the recycled object pool.
// Clear out all other details.
flags = FLAG_IN_USE;
what = 0;
arg1 = 0;
arg2 = 0;
obj = null;
replyTo = null;
sendingUid = -1;
when = 0;
target = null;
callback = null;
data = null;
synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool;
sPool = this;
sPoolSize++;
}
}
}
前半段不必多說,顯然是“重置”改對象的個個字段。後半段又是一個同步代碼段,同樣用圖來解釋一下(假設當前代碼為message.recycle()
,則需要被回收的則是message
對象)。
假設當前鏈表如下:
執行next=sPool;
執行sPool=this
;
現在可以很清楚的看到,Message類本身就組織了一個棧結構的緩沖池。並使用obtain()
方法和recycler()
方法來取出和放入。
listview是開發中必見的功能應用,各種需求也不盡相同,今天給大家一個帶來一個簡單方便的自定義listview,希望對大家有幫助,閒話不說,先上幾張效果圖1、功能示例
說到線程,我想大家都不陌生,因為在開發時候或多或少都會用到線程,而通常創建線程有兩種方式: 1、繼承Thread類 2、實現Runnable接口雖說這兩種方式都可以創建出
前言前面在介紹控件TabLayout控件和CoordinatorLayout使用的時候說了下實現京東、天貓詳情頁面的效果,今天要說的是優化版,是我們線上實現的效果,首先看
package com.example.baidulocdemo_2;import com.baidu.location.BDLocationListener;impor