theme: awesome-green
在android面試中白魂,我們常會遇到Framework面試相關(guān)問題槽片,而今天要分享的就是Looper無限循環(huán)的阻塞為啥沒有ANR何缓?
其主要考察的是程序員是否了解Looper的運行機制。
一般遇到此類問題我們可以從以下兩個方面去回答:
- Handler的內(nèi)部原理
- ANR發(fā)生的原因
問題正解:
1.首先回答ANR是什么筐乳?引起ANR的主要原因有哪些歌殃?
ANR(Application Not Responding)是應用無響應乔妈。ndroid系統(tǒng)對于一些事件需要在一定的時間范圍內(nèi)完成,如果超過預定時間能未能得到有效響應或者響應時間過長勃刨,都會造成ANR。
-
發(fā)生ANR的主要四種情況:
1)Service Timeout:前臺服務在20s內(nèi)未執(zhí)行完成身隐; 2)BroadcastQueue Timeout:前臺廣播在10s內(nèi)未執(zhí)行完成 3)ContentProvider Timeout:內(nèi)容提供者在publish過超時10s; 4)InputDispatching Timeout:輸入事件分發(fā)超時5s唯灵,包括按鍵和觸摸事件贾铝。
對于Service埠帕、Broadcast、Provider組件類的ANR而言敛瓷,如果把發(fā)生ANR比作是引爆炸彈,那么整個流程包含三部分組成:
埋炸彈:中控系統(tǒng)(system_server進程)啟動倒計時埋下定時器呐籽,在規(guī)定時間內(nèi)如果目標(Servcie、Broadcast庶橱、Provider)沒有干完所有的活,則中控系統(tǒng)會定向炸毀(殺進程)目標苏章,就相當于埋下一個定時炸彈馍乙。 拆炸彈:在規(guī)定的時間內(nèi)干完工地的所有活,并及時向中控系統(tǒng)報告完成丝格,請求解除定時炸彈,則幸免于難显蝌。 引爆炸彈:中控系統(tǒng)立即封裝現(xiàn)場订咸,抓取快照酬诀,搜集目標執(zhí)行慢的罪證(traces)脏嚷,便于后續(xù)調(diào)試分析,最后是炸毀目標父叙。
對于輸入超時肴裙,與其他3個組件類ANR是不同的趾唱,Input類型的超時機制并非時間到了一定就會爆炸蜻懦,而是處理后續(xù)上報事件的過程才會去檢測是否該爆炸,所以更像是掃雷過程悠咱。具體的邏輯是這樣的:對于輸入系統(tǒng)而言征炼,即使某次事件執(zhí)行時間超過預期的時長析既,只要用戶后續(xù)沒有再生成輸入事件柒室,那么也不需要ANR。而只有當新一輪的輸入事件到來雄右,此時正在分發(fā)事件的窗口(即App應用本身)遲遲無法釋放資源給新的事件去分發(fā),這時InputDispatcher才會根據(jù)超時時間囤屹,動態(tài)的判斷是否需要向?qū)拇翱谔崾続NR信息逢渔。
那么明白了ANR的原因后,我們再來看一下Looper的阻塞原理肃廓。
2.Looper無限循環(huán)如何導致阻塞的
- Looper無限循環(huán)是Looper不停取MessageQueen中的Message并執(zhí)行這個message的一種機制。我們的APP中的事件盲赊,如Activity的生命周期切換、點擊诚卸、長按、滑動合溺、都是依賴這種機制。
- 如果主線程的MessageQueue中沒有消息哮奇,便會阻塞在Loop的queue.next()中的nativePollOnce方法恭朗。這個時候主線程會進入休眠狀態(tài)并釋放CPU資源依疼,如果下一個消息到達或者有事物發(fā)生,通過向pipe管道寫入數(shù)據(jù)來進行喚醒主線程工作律罢。
3.Looper無限循環(huán)為啥沒有ANR?
- Looper循環(huán)的阻塞是在消息隊列無消息需要處理時的一種機制,這種機制就是讓CPU停下來去做別的事误辑。而且消息隊列無消息沧踏,那么就是需要需要讓cpu停下來巾钉,避免cpu空轉(zhuǎn),這個機制和ANR是沒有關(guān)系的砰苍,完全不是同一個事,所以自然不會導致ANR
今日分享到此結(jié)束茬缩,下期更精彩~
關(guān)注博主個人簡介吼旧,面試不迷路