天天看點

Looper的工作原理

Looper 在 Android 的消息機制中扮演着重要的角色,具體來說就是它會不停地從 MessageQueue 中檢視是否有新消息,如果有新消息就會立刻處理并删除消息,否則就一直阻塞在那裡。

我們知道,Handler 的工作需要 Looper,沒有 Looper 的線程就會報錯。

在一個 Activity 主線程中,我們可以直接使用 Handler,因為 在activity 主線程中,系統會通過 Looper.prepareMainLooper () 來建立主線程的 Looper 以及 MessageQueue,并通過 Looper.loop() 方法來開啟主線程的消息循環,是以不需要自己建立。

但是在 子線程中 要想使用 Handler 的話,怎麼在子線程中建立Looper呢?其實很簡單,通過Looper.prepare()即可為目前線程建立一個Looper,接着通過Looper.loop()來開啟消息循環。

在子線程中,如果手動為其建立了 Looper,那麼在所有的事情完成以後應該調用 quit 方法來終止消息循環,否則這個子線程就會一直處于等待狀态,而如果退出 Looper 以後,這個線程就會立刻終止,是以建議在不需要的時候終止 Looper。

Looper的 loop 方法是一個死循環,唯一跳出循環的方式是 MessageQueue 的next方法傳回null。當 Looper 的 quit 方法被

調用時,Looper就會調用 MessageQueue 的 quit 或者 quitSafely 方法來通知消息隊列退出,當消息隊列被标記為退出狀态

時,它的 next 方法就會傳回null。也就是說,Looper必須退出,否則loop方法就會無限循環下去。 loop 方法會調用 

MessageQueue 的 next 方法來擷取新消息,而 next 是一個阻塞操作, 當沒有消息時,next 會一直阻塞在那裡,這也導緻 

loop 方法一直阻塞在那裡。如果MessageQueue 的 next 方法傳回了新消息,Looper就會處理這條消息:

msg.target.dispatchMessage(msg), 這裡的 msg.target 是發送這條消息的 Handler 對象,這樣 Handler 發送的消息最終又

交給它的 dispatchMessage 方法來處理了。但是這裡不同的是,Handler 的dispatchMessage 方法是在建立 Handler 時所

使用的 Looper 中執行的,這樣就成功地将代碼邏輯切換到指定的線程中去執行了。

繼續閱讀