更多问答 >>
-
每日一问 对于SharedPreferences你觉得有什么优缺点?
2019-07-02 23:35 -
每日一问 | getWidth, getMeasuredWidth 有什么区别?
2019-07-05 00:48 -
每日一问 对于代码中有大量的 if/else 你有什么优化思路?
2019-07-07 23:00 -
每日一问 在Activity 的 onResume 方法中 handler.postRunnable 能获取到 View 宽高吗?
2019-07-09 21:03 -
每日一问 在Activity 的 onResume 方法中 view.postRunnable 能获取到 View 宽高吗?
2019-07-11 23:28 -
每日一问 | 为什么属性动画移动一个控件后,目标位置仍然能响应用户事件?
2019-06-27 23:50 -
每日一问 有没有使用过 DataBinding ,有什么优点、缺点,遇到过哪些坑?
2019-06-26 00:23 -
每日一问 View中的getContext一定返回的是Activity对象吗?
2019-06-23 22:18 -
每日一问 详细的描述下自定义 View 测量时 MesureSpec.UNSPECIFIED
2019-06-20 00:26 -
每日一问 自定义 ViewGroup 的时候,关于 LayoutParams 有哪些注意事项?
2019-06-15 21:09

源码分析:
打开ActivityManagerService的源码(在AS中先进入ActivityManager,再查找引用ActivityManager的类即能进入AMS),
在1891行(我使用的sdkVersion是28)可以看到:看名字能大概猜到,这就是弹出ANR对话框的message标识了,ctrl点下它,可以看到这个:可以看到它里面会调用AppErrors的handleShowAnrUi方法,这个方法里面它会创建一个AppNotRespondingDialog(系统的自定义Dialog),最终会以TYPE_SYSTEM_ERROR的方式弹出。到这里基本可以确定,弹出ANR对话框的条件就是AMS中的UiHandler收到了what为SHOW_NOT_RESPONDING_UI_MSG的消息,
那么这个消息是在哪里发出的呢?
ctrl点开1891行SHOW_NOT_RESPONDING_UI_MSG,会看到在AppErrors类中的appNotResponding方法里有引用:
可以看到,在这个方法里会给AMS(那个mService就是AMS的实例)的UiHandler发送请求弹出ANR对话框,那到底在哪些地方调用这个方法的呢?
一共有4处,分别是:
看方法名字:
UI线程执行一个非常耗时的操作一定会出现ANR弹框吗?
我们来看刚刚的inputDispatchingTimedOut方法的代码:
可以看到,调用appNotResponding方法(弹框)的,是在倒数第二行,但是!我们发现了有两种情况,是会直接return而不往下执行的(不弹框):
于是,有同学可能会使出一招"夺命连环问":
那什么情况下这个instr不为空呢(ANR时会直接被kill掉)?
它是当AMS的attachApplication方法被调用时,有可能被赋值。
什么时候attachApplication会被调用呢?
其实就是ActivityThread的main方法执行的时候(启动),它会调用一个attach方法,而attachApplication会在这个attach方法里面被调用。
赋值条件是什么?
赋值条件是mActiveInstrumentation里面不为空。
那么什么时候mActiveInstrumentation里面不为空?
看AMS代码7763行(检查mActiveInstrumentation是否为空那里)可以发现有一句注释:"Check if this is a secondary process",
那我们可以知道,这个判断是检测当前进程是否次进程(多进程环境下),如果是次线程(不是主进程),那么经过安全检查之后,就会把mActiveInstrumentation里面的实例,赋值给proc的instr。总结:
ANR对话框,是在AMS收到SHOW_NOT_RESPONDING_UI_MSG消息之后弹出的。这个消息分别来自于:
后台服务超时;前台服务超时;ContentProvider超时;input事件分派超时;在input事件分派超时的时候,有两种情况不会弹框,分别是:处于debug时;来自子进程;(这个情况下会直接kill掉子进程)真详细,点个赞
点赞!!!
暂,太喜欢这种叙述方式了
我的也是28,怎么没看到后面那些代码
ANR:Application Not Responding,即应用无响应
ANR类型:
1. KeyDispatchTimeout(5 seconds) --主要类型按键或触摸事件在特定时间内无响应
2. BroadcastTimeout(10 seconds) --BroadcastReceiver在特定时间内无法处理完成
3. ServiceTimeout(20 seconds) --小概率类型 Service在特定的时间内无法处理完成
其中,A key or touch event was not dispatched within the specified time(按键或触摸事件在特定时间内无响应)
具体的超时时间的定义在framework下的ActivityManagerService.java
//How long we wait until we timeout on key dispatching.
staticfinal int KEY_DISPATCHING_TIMEOUT = 5*1000
所以在UI线程中如果使用一个非常耗时的操作(>5S),是否会ANR应该取决于在这个过程中是否有收到 touch event ,如果有,那必然会产生ANR 弹窗,如果没有,理论上不会。
赞
AppErrors.appNotResponding();该方法是最终弹出ANR对话框的唯一入口,调用该方法的场景才会有ANR提示,也可以认为在主线程中执行无论再耗时的任务,只要最终不调用该方法,都不会有ANR提示,也不会有ANR相关日志及报告;通过调用关系可以看出哪些场景会导致ANR,有以下四种场景:
(1)Service Timeout:Service在特定的时间内无法处理完成;(2)BroadcastQueue Timeout:BroadcastReceiver在特定时间内无法处理完成(3)ContentProvider Timeout:内容提供者执行超时(4)inputDispatching Timeout: 按键或触摸事件在特定时间内无响应。更多内容你请参考:https://www.jianshu.com/p/ad1a84b6ec69