在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處理訊息。