轉自:https://www.cnblogs.com/MMLoveMeMM/articles/4849667.htmlhtml
這種問題主要是發生在兩個應用頁面之間切換的時候,這個臨界點的時候,一個頁面正在起來,另一個頁面已經"壓棧",即失去焦點,而且在這個頁面切換的時候快速點擊返回back鍵,按照目前android系統的約定是先判斷是否有window得到focus,發送按鍵message必需要有有效的focus窗口來接收,不然input event消息將會在系統裏面Block,一當Block,系統就開始計時(即timeout),時間一到即調用notifyANR開始處理timeout事件,表面現象APP無響應,而後崩潰掉.android
分析能夠參考以下 :app
谷歌develop官網上對ANR觸發機制是這樣描述的:
此處從
角度分析下AMS和WMS是如何monitor ANR的。
Android版本:Android 5.0
分析對象:keyDispatchingTimedOut的monitor機制
1. keyDispatchingTimedOut(此處‘key‘不許確,實際上是InputEvent(包含KeyEvent和TouchEvent)派發超時,當前觸屏手機上,以TouchEvent/MotionEvent爲主),先看下這塊的類圖:
能夠看到真正幹活的是在Native側,由native側monitor事件是否超時,並觸發調用Java側notifyANR邏輯。
anr monitor的大概時序以下:
ANR monitor核心工做由InputDispatcher.cpp完成,在每次派發事件時,須要進行以下判斷:
1. 判斷是否有focused
及focusedApplication
2. 判斷前面的事件是否及時完成
對於1,通常是在啓動時可能觸發,好比啓動時間過長,在這過程當中觸發keyevent或trackball motionevent, 則進行以下邏輯判斷:
這種狀況下,對應的ANR log以下:htm
Reason: Input dispatching timed out (Waiting because no window has focus but there is a focused application that eventually a window when it finishes starting up.)對象
對於2,KeyEvent和MotionEvent對「及時性」的策略不一樣,KeyEvent須要判斷上一個事件是否作完(因爲涉及focus的問題,KeyEvent必須等wms處理前一個事件,才把新的事件派發過去):
checkWindowReadyForMoreInputLocked
而touchevent(touch screen,e.g.),則需判斷事件等待隊列裏的
的事件時間是否已通過去0.5秒了,相對來講,touchevent的要求更
低些,容許的執行時延更大,此時,說明UI線程卡住了,一堆
event在等待執行,須要中止event delivery,
所以不管是keyevent(實體鍵輸入)仍是touchevent(點擊view)都是由於UI線程沒及時處理完前面的事件致使.
設置anr的start和timeout值,在timeout時刻喚醒事件,再依據上述條件判斷是否能夠event delivery,
若知足事件派發條件, 則能夠走正常派發流程,不然(如UI線程卡住、UI線程搶不到CPU等), 則觸發onANRLocked,後續流程如時序圖所示。
我感受上面分析比較好,比較實在.
另外附上全套android input處理流程 :