Android消息處理機(jī)制系列文章整體內(nèi)容如下
Android消息處理機(jī)制1——Handler
Android消息處理機(jī)制2——Message
Android消息處理機(jī)制3——MessageQueue
Android消息處理機(jī)制4——Looper
一 使用
Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare in the thread that is to run the loop, and then loop to have it process messages until the loop is stopped.
翻譯成中文是
Looper用于運(yùn)行線程的消息循環(huán),線程默認(rèn)沒有關(guān)聯(lián)looper;如果要創(chuàng)建一個looper壁酬,先在線程內(nèi)部調(diào)用prepare(),然后循環(huán)讓它處理消息酣栈,直到線程停止。
looper具體使用的例子
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
Android也提供了一個關(guān)聯(lián)looper的線程 HandlerThread
二 構(gòu)造器
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
創(chuàng)建Looper實(shí)例的時候會同時創(chuàng)建一個MessageQueue汹押,Looper只有一個私有的構(gòu)造器钉嘹,創(chuàng)建一個Looper實(shí)例只能通過
public static void prepare() {
prepare(true);
}
其內(nèi)部又調(diào)用私有方法
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
Looper是用ThreadLocal存儲的,ThreadLocal存儲的變量有一個特點(diǎn)鲸阻,就是只能被同一個線程讀寫跋涣。
上面的代碼的意思是,如果該線程已經(jīng)綁定一個Looper實(shí)例鸟悴,則拋出異常陈辱,否則就創(chuàng)建一個。
public static void prepareMainLooper()
主線程初始化的時候會調(diào)用prepareMainLooper來創(chuàng)建Looper實(shí)例
三 管理消息隊列
使用loop()方法來管理消息隊列细诸,通過loop()方法循環(huán)從MessageQueue里面取出消息沛贪,然后給handler處理。loop()方法里調(diào)用for(;;)形成死循環(huán),當(dāng)前線程在loop方法之后的方法都不會執(zhí)行利赋。下面分析loop方法的源碼
public static void loop() {
final Looper me = myLooper();
//代碼省略
for (;;) {
Message msg = queue.next(); // 取出messageQueue頭部的message水评,同時會把該message從messageQueue刪除
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
//代碼省略
try {
msg.target.dispatchMessage(msg); //msg.target獲取處理message的handler,其實(shí)就是發(fā)送該message的handler媚送,然后調(diào)用該handler的dispatchMessage方法中燥,將消息分發(fā)給該handler讓其進(jìn)行處理。
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
//代碼省略
msg.recycleUnchecked(); //將該msg初始化塘偎,并放入message池里面
}
}
loop()方法里做了三件事:
- 從messageQueue里面取出消息
- 將message分發(fā)給相應(yīng)的handler疗涉,讓handler處理
- 回收該message,將它放到消息池里面吟秩,消息池的數(shù)據(jù)結(jié)構(gòu)是一個先進(jìn)后出的鏈?zhǔn)綏?/li>
(完)
參考的文章:
Java ThreadLocal