古詩詞大全網 - 成語查詢 - Handler源碼分析

Handler源碼分析

Handler對於Android開發者再熟悉不過了,也是面試題的常客了,所以了解Handler機制的源碼就很有必要了,雖然Handler分析的文章已經有很多,但是自己總結壹遍,印象才更深刻。

Handler機制,是Android中的壹種消息傳遞機制,在開發中十分常用。由於Android從3.0開始不允許耗時操作在主線程中執行,必須在子線程中執行完後,將結果發送到主線程中更新UI。所以簡單來講Handler就是子線程和主線程通信的壹種技術。

先是常規使用,Handler在主線程中創建,開啟子線程處理耗時操作,再通過Handler發送消息到主線程,Handler的handleMessage()方法就會被回調,再更新UI。

以及也很常用的,post()和postDelayed()。

還有壹種場景,就是子線程中創建Handler,讓子線程成為輪訓的線程,接收其他線程的消息,開發中並不多,但是特定場景會很有用,例如有壹個壹直執行的子線程,壹直定時掃描著當前位置信息,到了指定範圍,發送壹個播放語音的消息的消息到主線程。

接下來就是Handler源碼分析了:

壹般我們獲取Message會調用Handler的obtainMessage()方法,這個方法是獲取壹個復用的Message對象,內部采用享元模式復用Message對象,在Android中,View繪制,Activity生命周期,都是使用Handler發送Message實現,如果每次都new壹個消息對象,肯定是十分消耗內存的,也容易產生GC垃圾回收導致卡頓。

我們平常在主線程使用Handler時,並沒有調用過Looper.prepare()和Looper.loop()這2個方法,為什麽創建Handler時不會拋出異常呢?

原因就是創建Handler時,調用Looper.myLooper()獲取主線程綁定的Looper不為空,所以沒有拋出異常。經過Looper類中查找發現,除了Looper.prepare()之外,還有壹個prepareMainLooper()的方法。

prepareMainLooper()方法的註釋,意思大概就是,創建主線程的Looper對象,該方法由Android框架在主線程自動調用,我們不應該主動調用該方法。

那麽什麽時候會調用prepareMainLooper()方法呢,AndroidStudio點擊方法查找調用鏈,我們發現在ActivityThread中有調用。ActivityThread是Android程序的主線程,main方法則是啟動的方法,我們看到先是調用了Looper.prepareMainLooper(),初始化主線程的Looper。再調用了Looper.loop()開啟主線程輪訓。