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 java

         {android

                  public Handler mHandler; 函數

                  public void run() oop

                          {ui

                                  Looper.prepare();spa

                                  mHandler = new Handler() .net

                                          {線程

                                                public void handleMessage(Message msg)code

                                                              { 對象

                                                                    // process incoming messages here

                                                              }

                                          };

                                  Looper.loop();

            }

另,Activity的MainUI線程默認是有消息隊列的。因此在Activity中新建Handler時,不須要先調用Looper.prepare()。

何時使用Looper.prepare()

當你的線程想擁有本身的MessageQueue的時候先Looper.prepare(),而後Looper.loop();
參照源碼:

 

  1. public static final void prepare() {     
  2.        if (sThreadLocal.get() != null) {     
  3.            throw new RuntimeException("Only one Looper may be created per thread");     
  4.        }     
  5.        sThreadLocal.set(new Looper());     
  6.    }     
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()建立了消息隊列就可讓消息處理在該線程中完成

相關文章
相關標籤/搜索