Android ANR Waiting because no window has focus问题分析

转自: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处理流程 :
Android 5.0(Lollipop)事件输入系统(Input System) : http://blog.csdn.net/jinzhuojun/article/details/41909159
相关文章
相关标签/搜索