Android 執行緒訊息迴圈機制
android.os.Looper:
Looper用於封裝了android執行緒中的訊息迴圈,預設情況下一個執行緒是不存在訊息迴圈(message loop)的,需要呼叫Looper.prepare()來給執行緒建立一個訊息迴圈,呼叫Looper.loop()來使訊息迴圈起作用,從訊息佇列裡取訊息,處理訊息。注:寫在Looper.loop()之後的程式碼不會被立即執行,當呼叫後mHandler.getLooper().quit()後,loop才會中止,其後的程式碼才能得以執行。Looper物件通過MessageQueue來存放訊息和事件。一個執行緒只能有一個Looper,對應一個MessageQueue。
//Handler不帶引數的預設建構函式:new Handler(),實際上是通過Looper.myLooper()來獲取當前執行緒中的訊息迴圈,classLooperThreadextendsThread{publicHandler mHandler;publicvoid run(){Looper.prepare();
//而預設情況下,執行緒是沒有訊息迴圈的,所以要呼叫Looper.prepare()來給執行緒建立訊息迴圈,然後再通過,Looper.loop()來使訊息迴圈起作用。
mHandler
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;
}
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也是隻有一個。