Android-Looper類,Looper.prepare()和Looper.loop()
阿新 • • 發佈:2019-01-29
Android中的Looper類,是用來封裝訊息迴圈和訊息佇列的一個類,用於在android執行緒中進行訊息處理。handler其實可以看做是一個工具類,用來向訊息佇列中插入訊息的。
(1) Looper類用來為一個執行緒開啟一個訊息迴圈。
預設情況下android中新誕生的執行緒是沒有開啟訊息迴圈的。(主執行緒除外,主執行緒系統會自動為其建立Looper物件,開啟訊息迴圈。)
Looper物件通過MessageQueue來存放訊息和事件。一個執行緒只能有一個Looper,對應一個MessageQueue。
(2) 通常是通過Handler物件來與Looper進行互動的。Handler可看做是Looper的一個介面,用來向指定的Looper傳送訊息及定義處理方法。
預設情況下Handler會與其被定義時所線上程的Looper繫結,比如,Handler在主執行緒中定義,那麼它是與主執行緒的Looper繫結。
mainHandler = new Handler() 等價於new Handler(Looper.myLooper()).
Looper.myLooper():獲取當前程序的looper物件,類似的 Looper.getMainLooper() 用於獲取主執行緒的Looper物件。
(3) 在非主執行緒中直接new Handler() 會報如下的錯誤:
E/AndroidRuntime( 6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception
E/AndroidRuntime( 6173): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
原因是非主執行緒中預設沒有建立Looper物件,需要先呼叫Looper.prepare()啟用Looper。
(4) Looper.loop(); 讓Looper開始工作,從訊息佇列裡取訊息,處理訊息。
注意:寫在Looper.loop()之後的程式碼不會被執行,這個函式內部應該是一個迴圈,當呼叫mHandler.getLooper().quit()後,loop才會中止,其後的程式碼才能得以執行。
(5) 基於以上知識,可實現主執行緒給子執行緒(非主執行緒)傳送訊息。
把下面例子中的mHandler宣告成類成員,在主執行緒通過mHandler傳送訊息即可。
Android官方文件中Looper的介紹:
Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.
Most interaction with a message loop is through the Handler class.
This is a typical example of the implementation of a Looper thread, using the separation of prepare() and loop() to create an initial Handler to communicate with the Looper.
Java程式碼 class LooperThread extends Thread {
(1) Looper類用來為一個執行緒開啟一個訊息迴圈。
預設情況下android中新誕生的執行緒是沒有開啟訊息迴圈的。(主執行緒除外,主執行緒系統會自動為其建立Looper物件,開啟訊息迴圈。)
Looper物件通過MessageQueue來存放訊息和事件。一個執行緒只能有一個Looper,對應一個MessageQueue。
(2) 通常是通過Handler物件來與Looper進行互動的。Handler可看做是Looper的一個介面,用來向指定的Looper傳送訊息及定義處理方法。
預設情況下Handler會與其被定義時所線上程的Looper繫結,比如,Handler在主執行緒中定義,那麼它是與主執行緒的Looper繫結。
mainHandler = new Handler() 等價於new Handler(Looper.myLooper()).
Looper.myLooper():獲取當前程序的looper物件,類似的 Looper.getMainLooper() 用於獲取主執行緒的Looper物件。
(3) 在非主執行緒中直接new Handler() 會報如下的錯誤:
E/AndroidRuntime( 6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception
E/AndroidRuntime( 6173): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
原因是非主執行緒中預設沒有建立Looper物件,需要先呼叫Looper.prepare()啟用Looper。
(4) Looper.loop(); 讓Looper開始工作,從訊息佇列裡取訊息,處理訊息。
注意:寫在Looper.loop()之後的程式碼不會被執行,這個函式內部應該是一個迴圈,當呼叫mHandler.getLooper().quit()後,loop才會中止,其後的程式碼才能得以執行。
(5) 基於以上知識,可實現主執行緒給子執行緒(非主執行緒)傳送訊息。
把下面例子中的mHandler宣告成類成員,在主執行緒通過mHandler傳送訊息即可。
Android官方文件中Looper的介紹:
Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.
Most interaction with a message loop is through the Handler class.
This is a typical example of the implementation of a Looper thread, using the separation of prepare() and loop() to create an initial Handler to communicate with the Looper.
Java程式碼 class
- public Handler mHandler;
- publicvoid run() {
- Looper.prepare();
- mHandler = new Handler() {
- publicvoid handleMessage(Message msg) {
- // process incoming messages here
- }
- };
- Looper.loop();
- }
- }