Android 之 Looper、MessageQueue、Handler 與消息循環

轉載: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處理消息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章