Android ANR 详解
ANR简介
- ANR,是“Application Not Responding”的缩写,即“应用程序无响应”。在Android中,ActivityManagerService(简称AMS)和WindowManagerService(简称WMS)会监测应用程序的响应时间,如果应用程序主线程(即UI线程)在超时时间内对输入事件没有处理完毕,或者对特定操作没有执行完毕,就会出现ANR。对于输入事件没有处理完毕产生的ANR,Android会显示一个对话框,提示用户当前应用程序没有响应,用户可以选择继续等待或者关闭这个应用程序(也就是杀掉这个应用程序的进程)。
为什么会有ANR
ANR的产生需要同时满足三个条件:
- 主线程:只有应用程序进程的主线程响应超时才会产生ANR;
- 超时时间:产生ANR的上下文不同,超时时间也会不同,但只要在这个时间上限内没有响应就会ANR
- 输入事件/特定操作:输入事件是指按键、触屏等设备输入事件,特定操作是指BroadcastReceiver和Service的生命周期中的各个函数,产生ANR的上下文不同,导致ANR的原因也会不同;
针对这三个条件,有以下三种情况会触发ANR,详细说明如下。
- 1、主线程对输入事件在5秒内没有处理完毕
Android的事件系统从2.3开始做了完全不同的实现,原先2.2中是在Java层实现的,但在2.3中整体转移到了C++层,本书基于2.3以后的版本进行说明。我们先简单了解一下产生这种ANR的整个流程。 当应用程序的Window处于Active状态并且能够接收输入事件(例如按键事件、触摸事件等)时,系统底层上报的事件就会被InputDispatcher分发给这个应用程序,应用程序的主线程通过InputChannel读取输入事件并交给界面视图处理,界面视图是一个树状结构,DecorView是视图树的根,事件从树根开始一层一层向端点(例如一个Button)传递。我们通常会注册一个监听器来接收并处理事件,或者创建自定义的视图控件来处理事件。 InputDispatcher运行在系统进程(进程名为system_server)的一个单独的线程中,应用程序的主线程在处理事件的过程中,InputDispatcher会不断的检测处理过程是否超时,一旦超时,会通过一系列的回调通知WMS的notifyANR函数,最终会调用到AMS中mHandler对象里的SHOW_NOT_RESPONDING_MSG这个case,此时界面上就显示系统提示对话框了,同时使用logcat命令查看log(日志信息)也可以看到关于ANR的信息。一下子出现了好几个重要的名词,要深入了解这种情况的ANR,需要熟悉Android的事件机制,本次不做解析,这里只需要记住他们的功能:
Window:具体指的是PhoneWindow对象,表示一个能够显示的窗口,它能够接收系统分发的各种输入事件;
InputDispatcher:将系统上报的输入事件分发给当前活动的窗口;
InputChannel:InputDispatcher和应用程序分别运行在两个不同的进程中,InputDispatcher就是通过InputChannel将事件对象传递给应用进程的。
注意:产生这种ANR的前提是要有输入事件,如果用户没有触发任何输入事件,即便是主线程阻塞了,也不会产生ANR,因为InputDispatcher没有分发事件给应用程序,当然也不会检测处理超时和报告ANR了。
2、主线程在执行BroadcastReceiver的onReceive函数时10秒内没有执行完毕
BroadcastReceiver(简称BR)的onReceive函数运行在主线程中,当这个函数超过10秒钟没有返回就会触发ANR。不过对这种情况的ANR系统不会显示对话框提示,仅是输出log而已。
3、主线程在执行Service的各个生命周期函数时20秒内没有执行完毕
Service的各个生命周期函数也运行在主线程中,当这些函数超过20秒钟没有返回就会触发ANR。同样对这种情况的ANR系统也不会显示对话框提示,仅是输出log。
三种ANR中只有第1种会显示系统提示对话框,因为用户正在做界面交互操作,如果长时间没有任何响应,会让用户怀疑设备死机了,大多数人此时会开始乱按,甚至拔出电池重启,给用户的体验肯定是非常糟糕的。
三种ANR发生时都会在log中输出错误信息,你会发现各个应用进程和系统进程的函数堆栈信息都输出到了一个/data/anr/traces.txt的文件中,这个文件是分析ANR原因的关键文件,同时在日志中还会看到当时的CPU使用率,这也是重要信息,可以利用它们分析ANR问题。
这三种ANR不是孤立的,有可能会相互影响。例如一个应用程序进程中同时有一个正在显示的Activity和一个正在处理消息的BroadcastReceiver,它们都运行在这个进程的主线程中。如果BR的onReceive函数没有返回,此时用户点击屏幕,而onReceive超过5秒仍然没有返回,主线程无法处理用户输入事件,就会引起第1种ANR。如果继续超过10秒没有返回,又会引起第2种ANR
Android ANR 详解的更多相关文章
- Android ANR详解
如何避免KeyDispatchTimeout 1:UI线程尽量只做跟UI相关的工作 2:耗时的工作(比如数据库操作,I/O,连接网络或者别的有可能阻碍UI线程的操作)把它放入单独的线程处理 3:尽量用 ...
- Android App优化之ANR详解
引言 背景:Android App优化, 要怎么做? Android App优化之性能分析工具 Android App优化之提升你的App启动速度之理论基础 Android App优化之提升你的App ...
- Android Notification 详解(一)——基本操作
Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...
- Android Notification 详解——基本操作
Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...
- Android ActionBar详解
Android ActionBar详解 分类: Android2014-04-30 15:23 1094人阅读 评论(0) 收藏 举报 androidActionBar 目录(?)[+] 第4 ...
- Android 签名详解
Android 签名详解 AndroidOPhoneAnt设计模式Eclipse 在Android 系统中,所有安装 到 系统的应用程序都必有一个数字证书,此数字证书用于标识应用程序的作者和在应用程 ...
- Android编译系统详解(一)
++++++++++++++++++++++++++++++++++++++++++ 本文系本站原创,欢迎转载! 转载请注明出处: http://blog.csdn.net/mr_raptor/art ...
- Android布局详解之一:FrameLayout
原创文章,如有转载,请注明出处:http://blog.csdn.net/yihui823/article/details/6702273 FrameLayout是最简单的布局了.所有放在布局里的 ...
- 【整理修订】Android.mk详解
Android.mk详解 1. Android.mk 的应用范围 Android.mk文件是GNU Makefile的一小部分,它用来对Android程序进行编译. 一个Android.mk文件可以编 ...
随机推荐
- 【PHP项目】$_SEVER详解
$_SERVER['HTTP_ACCEPT_LANGUAGE']//浏览器语言 $_SERVER['REMOTE_ADDR'] //当前用户 IP . $_SERVER['REMOTE_HOST'] ...
- python之doctest的用法
doctest是python自带的一个模块,你可以把它叫做“文档测试”(doctest)模块. doctest的使用有两种方式:一个是嵌入到python源中.另一个是放到一个独立文件. doctest ...
- google云函数实现BigQuery数据操作
Google Cloud Function操作BigQuery数据库. 1.部署云函数时在配置文件中(package.json)添加一项 "@google-cloud/bigquery&qu ...
- 呕心沥血写的python猜数字
#猜数字 import random num_rd=random.randint(0,100) count=1 while 1<=count<=10: num_ip=input('请输入0 ...
- 1016-01-首页16-计算配图的frame----MJExtention的使用
-------HWPhoto.h--------------------------------------------- #import <Foundation/Foundation.h> ...
- 寻找物体的凸包 opencv
凸包的含义: 在二维平面上给定点集,凸包就是将最外层的点连接起来构成的凸多边形.并且这个凸多边形能包含点集中所有的点.OPENCV中: convexHull函数用于寻找图像点集中的凸包.它有六个输入参 ...
- 进入saftmode解决方案
Name node is in safe mode.The reported blocks 356 needs additional 2 blocks to reach the threshold 0 ...
- TouTiao开源项目 分析笔记17 新闻媒体专栏
1.效果预览 1.1.要实现的效果 1.2.如何调转到新闻媒体专栏 点击右上角的用户图标. 在新闻详情页面的Fragment的菜单点击事件中触发. case R.id.action_open_medi ...
- JS:关于JS字面量及其容易忽略的12个小问题
简要 问题1:不能使用typeof判断一个null对象的数据类型 问题2:用双等号判断两个一样的变量,可能返回false 问题3:对于非十进制,如果超出了数值范围,则会报错 问题4:JS浮点数并不精确 ...
- sqlsever存储过程学习笔记
1,创建数据表 use test create table money( id ,) primary key, money int, monetary_unity char ); 2,考虑到货币单位的 ...