Android looper、handler及HandlerThread
一、簡介
在Android開發中,使用消息隊列(message)完成線程間通信。而使用消息隊列的線程就是消息循環(message looper)。消息循環不斷的檢查消息隊列,是否有新消息。消息循環是由一個線程和一個looper組成;looper對象管理著線程的消息隊列。
Android的主線程也是一個消息循環,也具有一個Looper,主線程所有的任務都是由looper完成。消息循環是由一個線程和一個looper組成,looper對象管理著線程的消息隊列;因此,looper不斷的從消息隊列中抓取消息,然後完成消息指定的任務。
PS: 線程默認情況下,是沒有消息循環(Looper)的,在Android中,只有主線程默認就是Looper(消息循環)。在新創建的線程中,使用Looper,要先創建一個Looper才行。
二、Message與Handler
Message與Handler是成對出現的,Message是消息,而Handler是消息要完成任務的對象。
消息是Message的一個實例,在實現一個消息時,要同時實現Message類的一些實例變量,
-
- what: 用戶定義的Int類型消息代碼,用來描述消息。
- obj: 隨消息一起發送的用戶指定的對象,即消息傳遞的數據。
- target:完成消息指定任務的目標,即用來完成消息指定任務的對象。
Handler是完成消息或消息指定任務的對象,Handler不僅是完成消息的目標或對象,也是創建和發布消息(Message)的接口。
(圖來源於Android權威指南)
- Looper擁有message的消息隊列,所以,message必須在Looper上發布或讀取。
- 一個Handler僅一個Looper相關聯,一個Message也僅與一個目標Handler(message目標)相關聯。而Looper擁有消息的整個隊列。
在看看下面這個圖,
(圖來源於Android權威指南)
從上面這個圖中,可以看出,有多個Handler與一個Looper相關聯,這說明一個Handler的message與另一個Handler的message放於同一個消息隊列。
三、Handler使用
1. 使用Handler.obtainMessage(...)方法會從公共循環消息隊列中,獲取message。
2. 使用Handler.sendToTarget()方法,會方法消息發送給與message相關聯的Handler。而Handler會將message放於Looper的消息隊列尾部。
3. Looper在消息隊列中,獲取到特定的消息後,將其發送給消息目標(與之相關聯的Handler)去處理。消息一般在Handler(消息目標)的handlerMessage(...)實現方法處理消息指定要完成的任務。一般,要繼承Handler基類,覆蓋handlerMessage()方法。
四、傳遞Handler
Handler類的一個實例,可以作為函數參數,傳遞給其它子線程。
主線程擁有一個Handler和Looper消息循環,在線程中,主線程上創建一個Handler,會自動與主線程的Looper相關聯。將主線程創建的Handler傳遞給另一個子線程,傳遞出去的Handler始終會與創建它的線程的Looper保持聯系。因此,任何已傳出的Handler負責處理的消息,都將在主線程的消息隊列中處理。
那麽,就可以通過這種方式,在子線程中,去更新主線程的事件,數據,或者UI。
五、在新線程中,創建Looper(消息循環)
Android looper、handler及HandlerThread