面試常問Handler 的問題合集

問:怎麼保證一個線程只有一個handler?

呵呵呵,給的問題都是錯的。一個線程裏面可以有多個handler,但是隻有一個looper 和一個MessageQeue.
因爲Looper 的構造方法是私有的,所以只有 prepare 方法纔可以new Looper,但是這個方法只能調用一次,因爲第二次調用會拋異常。原因是Looper 這個類裏面有個static final 的變量,叫做sthreadLocal,調用prepare 的時候,會調用threadLocal.get(),如果返回值不爲空,就會拋異常。
多個handler 無所謂啊,因爲用handler 發送消息,msg 裏面有一個target 指向發消息的handler,處理消息的時候,會調用msg.target disapatch msg.

問:MessageQeue內部怎麼實現的消息隊列?先有一個延遲消息,後來有個直接發的消息,爲什麼後來直接發的消息先執行?

想想也知道,肯定要排序啊。我的天。感覺handler 還有很多細節,沒有看。native 的也沒有看。MessageQeue 是鏈表實現的, 因爲發送的消息可能被插入到任何位置,應對隨機插入數據,最好的數據結構就是鏈表。消息插入的時候,會根據deley time 進行排序插入,所以,就算是先發了一個延遲消息,又發送了立刻執行的消息,先執行的是後面立即執行的消息。

問:爲什麼不同的線程,調用Loop.myLooper()就可以得到當前自己線程的Looper 對象? 而不是所有線程獲取的是同一個Looper?

因爲Looper.myLooper 返回值是從ThreadLocal 裏面獲取的,不同的線程有不同的值。

問:爲什麼到了時間就處理消息?是有定時嗎?

問:爲什麼message.obtain 可以獲取message對象? 可以用到之前回收的message對象?

因爲message 裏面裏有私有的靜態變量,Message,保存了當前的回收了的message的頭結點。因爲是靜態的,所以所有的message 公用一個message 靜態變量。

問:Nativepollonce 爲什麼要使用c層去寫?java 層不能完全實現嗎?

因爲java 層不好控制休眠。因爲looper 是個死循環,當消息隊列沒有消息的時候,就會阻塞,釋放cpu。(sleep 也可以啊。)當有消息的時候,會喚醒程序運行。

問:android looper 爲什麼不會阻塞線程?

android 程序的主入口在activityThread 類的main 方法。裏面做了幾個簡單的事情,隨後啓動了looper. 如果不啓動looper 那麼程序就會直接退出了。所以looper 不但不會導致阻塞,反而會導致程序結束。所有的其他的操作,比如16ms 刷新一幀,都是通過hanlder 的handlermessage 去完成的。所以整個android 就是在handler 裏面完成所有的onResume,onPause,而程序不會退出。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章