轉載:http://blog.csdn.net/xieqibao/article/details/6563739
在android的activity中有各種各樣的事件,而這些事件最終是轉換爲消息來處理的。android中的消息系統涉及到:
* 消息發送
* 消息隊列
* 消息循環
* 消息分發
* 消息讀取
消息對應的重要類有MessageQueue、Looper、Handler,它們分別對應着消息隊列、消息循環和消息處理。
Handler類:
Handler主要用來發送消息和處理消息。每個handler實例都對應着一個線程和該線程的消息隊列。
當你創建一個handler對象時,該handler對象就屬於創建它的線程,並和該線程的消息隊列綁定,比如在主線程中創建handler對象,那麼該handler就只屬於主線程,並且和主線程的消息隊列綁定。(當然,每個線程都有自己的消息隊列,在android中,消息隊列是針對與線程的)。這樣,該handler就可以發送消息到該消息隊列並且處理該消息隊列的消息了。
當執行一些費時的操作時,比如需要遠程網絡訪問、下載等操作時,一般情況下都會啓動一個新的線程去操作。而不會放在ui線程去做,這樣可以防止android的5秒無相應導致的ANR異常。子線程中返回的結果怎樣更新到ui線程呢,這時就可以通過handler來處理了。可以在主線程中定義handler,然後通過主線程handler把子線程中的消息發送到主線程對應的消息隊列。在主線程中通過handler.handlerMessage就可以處理消息了,並更新到ui了。
我們剛纔說過,Handler主要是用來發送、處理消息的。那麼消息循環、隊列是在哪裏管理的。答案是:Looper、MessageQueue中。
Looper類:
looper類主要用來開啓線程的消息循環。默認情況下,系統在啓動的時候會爲主線程創建消息循環。其他新創建的線程則沒有,
如果需要,可以在該線程內調用Looper.prepare()來啓用looper對象,然後調用Looper.loop()進入消息循環。
這樣該線程就具有消息循環機制了,比如:
* 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();
* }
* }
實際上消息隊列也是在Looper中創建的,看下Looper的loop()方法,這個方法就是用來做消息循環用的。
* public static final void loop() {
* Looper me = myLooper(); //獲得當前線程的Looper對象
* MessageQueue queue = me.mQueue; //獲得當前線程的消息隊列
* while (true) { //條件爲true、一直循環執行。消息循環
* Message msg = queue.next(); // might block
* //if (!me.mRun) {
* // break;
* //}
* if (msg != null) {
* if (msg.target == null) {
* // No target is a magic identifier for the quit message.
* return;
* }
* if (me.mLogging!= null) me.mLogging.println(
* ">>>>> Dispatching to " + msg.target + " "
* + msg.callback + ": " + msg.whclearForRecycleat
* );
* msg.target.dispatchMessage(msg); //消息分發
* if (me.mLogging!= null) me.mLogging.println(
* "<<<<< Finished to " + msg.target + " "
* + msg.callback);
* msg.recycle(); //消息已經分發出去,對消息進行回收處理
* }
* }
* }
我們再來看Handler的構造函數,在Handler的構造函數中獲得當前線程的Looper對象、和消息隊列。消息隊列也是從looper中獲得的,剛纔我們說過。
* public Handler() {
* if (FIND_POTENTIAL_LEAKS) {
* final Class<? extends Handler> klass = getClass();
* if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
* (klass.getModifiers() & Modifier.STATIC) == 0) {
* Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
* klass.getCanonicalName());
* }
* }
* //在Handler的構造函數中獲得當前線程的Looper對象、和消息隊列。消息隊列也是從looper中獲得的
* mLooper = Looper.myLooper();
* if (mLooper == null) {
* throw new RuntimeException(
* "Can't create handler inside thread that has not called Looper.prepare()");
* }
* mQueue = mLooper.mQueue;
* mCallback = null;
* }
在handler中還有一些重要的方法:
handleMessage(Message) //處理消息
dispatchMessage(Message) //分發消息
sendMessage(Message) //發送消息
到這裏我們大致可以瞭解android中的消息流程大概是這樣的:
Handler獲得當前線程的Looper、MessageQueue,並且發送消息到MessageQueue中。 Looper對消息做循環,並通過 msg.target.dispatchMessage來分發消息(target應該就是handler)。然後Handler.handlerMessage處理消息