今天**android中的訊息機制,主要包括訊息的傳送、接收以及與執行緒之間的關係。完成這一過程主要需要以下三個類的協作:looper,handler,messagequeue。先給出乙個總體圖:
每乙個looper都會和乙個執行緒繫結。要建立乙個新的looper並將它同當前的執行緒繫結起來,你必須要呼叫looper.prepare()方法。這些looper都被儲存在looper類裡面的靜態threadlocal變數裡面。你可以通過呼叫looper.mylooper()方法來獲取與當前執行緒相關聯的looper。
class looper
sthreadlocal.set(new looper());
}
//...
//訊息迴圈
public static final void loop()
if (msg != null)
if (me.mlogging!= null) me.mlogging.println(
">>>>> dispatching to " + msg.target + " "
+ msg.callback + ": " + msg.what
);
msg.target.dispatchmessage(msg);
if (me.mlogging!= null) me.mlogging.println(
"<<<<< finished to " + msg.target + " "
+ msg.callback);
msg.recycle();
} }
}
//返回和執行緒相關的looper
public static final looper mylooper()
}
handler
handler配合looper完成訊息的傳送及分發處理。即:
1、從任意執行緒傳送訊息給looper的訊息佇列;2、處理相關聯的looper發過來的訊息。
乙個looper可以關聯多個handler。looper會把message傳送到message.target(它就是乙個handler,通過msg.target = this; 設定)。例如,在activity中新建的handler成員變數,都是關聯到主線程的looper中的。
handler的無參建構函式會獲取與當前執行緒相關聯的looper。你要確認當前執行緒是否是你的handler想要關聯的執行緒。
handler handler = new handler();
這樣做會更明確地關聯到ui執行緒:
handler handler = new handler(looper.getmainlooper());
看看handler的主要原始碼:
class handler
//直接把looper的queue和自己的queue設定 同乙個,這樣的話,通過handler的封裝機制加訊息的話,就相當於直接加到了looper的訊息佇列中去了
mqueue = mlooper.mqueue;
mcallback = null;
}//還有好幾種建構函式,乙個是帶callback的,乙個是帶looper的
//由外部設定looper
public handler(looper looper)
// 帶callback的,乙個handler可以設定乙個callback。如果有callback的話,
//凡是發到通過這個handler傳送的訊息,都有callback處理,相當於乙個總的集中處理
//待會看dispatchmessage的時候再分析
public handler(looper looper, callback callback)
//通過handler傳送訊息
//呼叫了內部的乙個sendmessagedelayed
public final boolean sendmessage(message msg)
//ft,又封裝了一層,這回是呼叫sendmessageattime了
//因為延時時間是基於當前呼叫時間的,所以需要獲得絕對時間傳遞給sendmessageattime
public final boolean sendmessagedelayed(message msg, long delaymillis)
return sendmessageattime(msg, systemclock.uptimemillis() + delaymillis);
}
public boolean sendmessageattime(message msg, long uptimemillis)
else
return sent;
} //還記得looper中的那個訊息迴圈處理嗎
//從訊息佇列中得到乙個訊息後,會呼叫它的target的dispatchmesage函式
//message的target已經設定為handler了,所以
//最後會轉到handler的msg處理上來
//這裡有個處理流程的問題
public void dispatchmessage(message msg) else
} //否則交給派生處理,基類預設處理是什麼都不幹
handlemessage(msg);
} }
}
要建立handler,首先要有looper,才能建立訊息系統。
ui更新
android的訊息機制就很好地解決了這個問題:乙個message經由handler的傳送,messagequeue的入隊,looper的抽取分發,又再一次地回到handler的處理。繞過的這一圈,正好幫助我們將同步操作變成了非同步操作。
我們知道,要正常地更新ui,主要有以下4種方式可以從其它執行緒訪問ui執行緒:
1、activity.runonuithread(runnable)2、view.post(runnable)3、view.postdelayed(runnable, long)4、handler
重點說一下的是view.post(runnable)方法。在post(runnable action)方法裡,view獲得當前執行緒(即ui執行緒)的handler,然後將action物件post到handler裡。在handler裡,它將傳遞過來的action物件包裝成乙個message(message的callback為action),然後將其投入ui執行緒的訊息迴圈中。在handler再次處理該message時,有一條分支(dispatchmessage中)就是為它所設,直接呼叫runnable的run方法。而此時,已經路由到ui執行緒裡,因此,我們可以毫無顧慮的來更新ui。
view.post處理訊息的分支(第乙個if分支):
public void dispatchmessage(message msg) else
} //否則交給派生處理,基類預設處理是什麼都不幹
handlemessage(msg);
} }
主線程
public class activitythread
looper.loop();
}}
所以,在activity中新建的handler成員變數,或者在新建handler時傳遞給建構函式的引數是looper.getmainlooper()的handler,都是在主線程的訊息迴圈佇列中的。
參考:1、
2、3、
4、
Android中訊息機制詳解
android 執行緒問題主要概念 1 messagequeue 是一種資料結構,見名知義,就是乙個訊息佇列,存放訊息的地方。每乙個執行緒最多隻可以擁有乙個messagequeue資料結構。建立乙個執行緒的時候,並不會自動建立其messagequeue。通常使用乙個looper物件對該執行緒的mes...
Android的訊息機制
android的訊息機制主要是指handler的執行機制,而handler的執行離不開messagequeue和looper的支撐。其中messagequeue稱為訊息佇列,用作儲存一組訊息,並以佇列的形式對外提供插入和刪除工作 具體實現 使用單鏈表的結構來儲存訊息列表 messagequeue不能...
Android 的訊息機制
handler是android的訊息機制的上層介面,這使得在開發過程中只需要和handler互動即可,通過它可以很輕鬆地將乙個任務切換到handler所在的執行緒中去執行。android的訊息機制主要是指handler的執行機制,handler的執行需要底層的messageqeue和looper的支...