經常可以在Android系統上發現ANR異常響應的問題。故瞭解一下ANR出現的原因
一、
Android系統中,應用程序的響應是由ActivityManager 和 WindowManger系統服務監視的,當它檢測到以下情況時,Android就會針對特定的應用程序顯示ANR:
1. 主線程超過5S沒有響應輸入事件。(主要類型)KeyDispatchTimeout(5 seconds)
2. BroadcastReceiver 沒有在10S 內返回。例如發送廣播更改“控件屬性”超過10S無效
3. Service在20S 內沒有無法完成處理(小概率)
二、
什麼是主線程(UI線程):
當一個程序第一次啓動時,Android會同時啓動一個對應的主線程(Main Thread),主線程主要負責處理與UI相關的事件,如:用戶的按鍵事件,用戶接觸屏幕的事件以及屏幕繪圖事件,並把相關的事件分發到對應的組件進行處理。所以主線程通常又被叫做UI線程。
三、
爲什麼UI線程沒有響應:
1. 當前的事件沒有機會得到處理
2. 當前的事件正在處理,但是沒有及時完成
四、
如何避免ANR:
1. 運行在主線程裏的任何方法都儘量少的做事情,特別是Activity的關鍵生命週期方法,再更新UI時儘量用handler進行。
2. 避免在BroadcastReceiver中做耗時的操作或者計算,如果響應廣播時要做耗時操作的話可以使用“service”來進行。
五、
容易出現ANR的場景:
1. 耗時的網絡訪問
2. 大量的數據庫讀寫操作
3. 系統硬件操作
4. 調用thread_join() / Sleep() / Wait() 或者等待locker的時候
5. 同時運行的Service binder達到上線(binder主要是用來進程間通信的,但也可用在和本地service通信)
6. Service響應超時
7. 非主線程持有lock,導致主線程等待lock超時
8. 非主線程終止或者崩潰導致主線程一直等待