天天看點

Android中為什麼主線程不會因為Looper.loop()裡的死循環卡死?

這個問題很簡單,概念了解問題,不需要把app啟動源碼牽扯進來搞得很複雜。

程式無響應:主線程執行任務時間較長,導緻其他需要立刻在主線程處理的事件無法得到處理。

線程阻塞:線程處于等待狀态

線程結束:線程的run方法傳回

阻塞與程式無響應沒有必然關系,雖然主線程在沒有消息可處理的時候是阻塞的,但是隻要保證有消息的時候能夠立刻處理,程式是不會無響應的。

阻塞與線程退出也沒有必然聯系,線程完全可以在不阻塞的情況下死循環,同樣達到不退出的效果。阻塞考慮到節約系統資源而做的處理,和線程退出沒有關系。

ActivityThread的main方法主要就是做消息循環,一旦退出消息循環,那麼你的應用也就退出了,Looer.loop()方法可能會引起主線程的阻塞,但隻要它的消息循環沒有被阻塞,能一直處理事件就不會産生ANR異常。

消息隊列是一個無限循環,為什麼無限循環不會ANR?因為可以說,應用的整個生命周期就是運作在這個消息循環中的,安卓是由事件驅動的,Looper.loop不斷的接收處理事件,每一個點選觸摸或者Activity每一個生命周期都是在Looper.loop的控制之下的,looper.loop一旦結束,應用程式的生命周期也就結束了。我們可以想想什麼情況下會發生ANR,第一,事件沒有得到處理,第二,事件正在處理,但是沒有及時完成,而對事件進行處理的就是looper,是以隻能說事件的處理如果阻塞會導緻ANR,而不能說looper的無限循環會ANR