1. 程式人生 > >Android 執行緒訊息迴圈機制

Android 執行緒訊息迴圈機制

android.os.Looper:

Looper用於封裝了android執行緒中的訊息迴圈,預設情況下一個執行緒是不存在訊息迴圈(message loop)的,需要呼叫Looper.prepare()來給執行緒建立一個訊息迴圈,呼叫Looper.loop()來使訊息迴圈起作用,從訊息佇列裡取訊息,處理訊息。

注:寫在Looper.loop()之後的程式碼不會被立即執行,當呼叫後mHandler.getLooper().quit()後,loop才會中止,其後的程式碼才能得以執行。Looper物件通過MessageQueue來存放訊息和事件。一個執行緒只能有一個Looper,對應一個MessageQueue。

以下是Android API中的一個典型的Looper thread實現:
//Handler不帶引數的預設建構函式:new Handler(),實際上是通過Looper.myLooper()來獲取當前執行緒中的訊息迴圈,
//而預設情況下,執行緒是沒有訊息迴圈的,所以要呼叫Looper.prepare()來給執行緒建立訊息迴圈,然後再通過,Looper.loop()來使訊息迴圈起作用。
classLooperThreadextendsThread{publicHandler mHandler;publicvoid run(){Looper.prepare();
          mHandler
=newHandler(){
publicvoid handleMessage(Message msg){// process incoming messages here}};Looper.loop();}}

另,Activity的MainUI執行緒預設是有訊息佇列的。所以在Activity中新建Handler時,不需要先呼叫Looper.prepare()。

android.os.Handler:

Handler用於跟執行緒繫結,來向執行緒的訊息迴圈裡面傳送訊息、接受訊息並處理訊息。

以下是不帶引數的Handler構造器:

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());
            }
        }

        mLooper = Looper.myLooper();
        if (mLooper == null) {

//如果當前執行緒裡面沒有訊息迴圈的時候,系統丟擲異常。即在一個執行緒裡如果想用Handler來處理訊息,是需要呼叫Looer.prepare()來建立訊息迴圈的,而MainUI執行緒不需要。

            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = null;
    }

通過以下函式來向執行緒傳送訊息或Runnable: 1、post(Runnable)postAtTime(Runnable, long)postDelayed(Runnable, long);   當執行緒接收到Runnable物件後即立即或一定延遲呼叫。 2、sendEmptyMessage(int)sendMessage(Message)sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long)。   當執行緒接受到這些訊息後,根據你的Handler重構的handleMessage(Message)根據接收到的訊息來進行處理。 另,一個Activity主執行緒中可以有多個Handler物件,但MessageQueueLooper是隻有一個,對應的Looper也是隻有一個。