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()來使訊息迴圈起作用。
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();
}
}
另,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也是只有一個。