回答這個問題先來了解一下下面幾個點
-
1.什么是ANR? ANR發生的原因是什么?
ANR 即 Application Not responding ,應用程序無響應
在android中,一般情況下,四大組件均是工作在主線程的,Android中的ActivityManager和WindowManager會隨時監控應用程序的響應情況,如果因為一些耗時操作(網絡請求或者IO操作)造成主線程阻塞一定時間(例如造成5s內不能響應用戶事件或者BroadcastReceiver的onReceive方法執行時間超過10s),那么系統就會顯示ANR對話框提示用戶對應的應用處于無響應狀態。
主線程Looper從消息隊列中讀取消息,當讀完所有消息時,主線程阻塞,子線程往消息隊列發送消息,并且往管道文件寫數據,主線程即被喚醒, 從管道文件讀取數據,主線程被喚醒只是為了讀取消息,當消息讀取完畢,再次睡眠,因此loop的循環并不會對cpu性能有過多的 消耗。 -
2. Looper為什么要無限循環?
Looper在prepare中通過ThreadLocal保證了每個線程Looper對象的唯一性,即對于每個線程,有唯一的Looper對象和MessageQueue隊列
主線程中如果沒有looper進行循環,那么主線程一運行完畢就會退出,Looper主要是做消息循環,然后由Handler進行消息分發處理,一旦退出消息循環,那么應用程序也就退出了。
主線程在main方法中開了一個阻塞式死循環,保證我們的應用程序不會退出
ANR的原因是因為Looper對象MessageQueue隊列中的事件沒有能夠得到及時執行
兩方面回答:
- 死循環不是造成ANR的必然原因,ANR是因為消息隊列當中的事件沒有及時得到處理造成的。(但是我們寫個死循環,基本上都會造成ANR,原因是主線程一直在這里循環,后面的事件沒有得到及時處理)
- 主線程的Looper循環,不會ANR最多就是OOM
參考鏈接: