1. 程式人生 > >Looper.loop() android執行緒中的訊息迴圈

Looper.loop() android執行緒中的訊息迴圈

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()。

當你的執行緒想擁有自己的MessageQueue的時候先Looper.prepare(),然後Looper.loop();
參照原始碼:
public static final void prepare() {   
       if (sThreadLocal.get() != null) {   
           throw new RuntimeException("Only one Looper may be created per thread");   
       }   
       sThreadLocal.set(new Looper());   
   }   
這段程式碼就是通過ThreadLocal來產生一個Looper物件做為執行緒區域性變數,然後呼叫Looper.loop()則是取出Looper物件中的MessageQueue進行訊息迴圈了,這樣形成了這個執行緒的訊息佇列。
一般情況下只會有主執行緒會呼叫prepare方法(ActivityThread的main函式)。

使執行緒擁有自己的訊息列隊,主執行緒擁有自己的訊息列隊,一般執行緒建立時沒有自己的訊息列隊,訊息處理時就在主執行緒中完成,如果執行緒中使用Looper.prepare()和Looper.loop()建立了訊息佇列就可以讓訊息處理在該執行緒中完成