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

转自:https://www.cnblogs.com/MMLoveMeMM/articles/4849667.html

这种问题主要是发生在两个应用页面之间切换的时候,这个临界点的时候,一个页面正在起来,另外一个页面已经"压栈",即失去焦点,并且在这个页面切换的时候快速点击返回back键,按照目前android系统的约定是先判断是否有window获得focus,发送按键message必须要有有效的focus窗口来接收,否则input event消息将会在系统里面Block,一当Block,系统就开始计时(即timeout),时间一到即调用notifyANR开始处理timeout事件,表面现象APP无响应,然后崩溃掉.

分析可以参考如下 :

Ref:

http://developer.android.com/training/articles/perf-anr.html

http://stackoverflow.com/questions/3467205/android-key-dispatching-timed-out

http://blog.csdn.net/wuhengde/article/details/8007448

谷歌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如下:

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

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Vue刷新页面有哪几种方式

在Vue项目中,刷新当前页除了window.reload(),你还能想到什么办法?而且这种办法会重新加载资源出现短暂的空白页面。体验不是很好。在某个详情页面的时候,我们经常需要通过路由中的详情id去获取内容,当我们在不同的详情页来回切换的时候,打开的页面是同一个,只是需要通过监听路由中的参数id的变化去重新请求详情接口。如果这个详情页只需要一个接口

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