[转发]Android 系统稳定性 - ANR(一)
文章都为原创,转载请注明出处,未经允许而盗用者追究法律责任。
很久之前写的了,留着有点浪费,共享之。
编写者:李文栋
http://rayleeya.iteye.com/blog/1955652
如果你是一个Android应用程序开发人员,你的人生中不可避免的三件事情是:死亡、缴税和ANR。这么说是夸张了,但是由于Android本身的设计,以及应用程序和系统在开发过程中的缺陷,经常会在测试过程中遇到各种各样的ANR问题。在功能性的测试中还少一些,主要是在压力测试中(例如Monkey测试)会遇到非常多的ANR问题。本章的目的就是汇总笔者在工作中遇到的各种ANR问题,将其归纳总结出一套分析和处理ANR问题的方法,希望能够通过这套方法为大家提供思路,有效的减少大家处理ANR问题的时间。同时也会给出一些避免ANR的最佳实践,更多的从预防做起,更少的做事后补救。
考虑到看本文的读者大多是有实际经验的开发人员,我会尽量少的提到一些基础的概念,我也希望给大家更多的“干货”。
本章的主要内容如下:
ANR简介(什么是ANR、为什么会有ANR、ANR的异常长什么样)
如何分析ANR(引起ANR的原因分类、分析ANR的利器)
实例讲解
避免ANR的最佳实践(从错误中吸取教训)
1.1 ANR简介
ANR,是“Application Not Responding”的缩写,即“应用程序无响应”。在Android中,ActivityManagerService(简称AMS)和WindowManagerService(简称WMS)会监测应用程序的响应时间,如果应用程序主线程(即UI线程)在超时时间内对输入事件没有处理完毕,或者对特定操作没有执行完毕,就会出现ANR。对于输入事件没有处理完毕产生的ANR,Android会显示一个对话框,提示用户当前应用程序没有响应,用户可以选择继续等待或者关闭这个应用程序(也就是杀掉这个应用程序的进程)。
1.1.1 为什么会有ANR
如上所述,ANR的产生需要同时满足三个条件:
主线程:只有应用程序进程的主线程响应超时才会产生ANR;
超时时间:产生ANR的上下文不同,超时时间也会不同,但只要在这个时间上限内没有响应就会ANR;
输入事件/特定操作:输入事件是指按键、触屏等设备输入事件,特定操作是指BroadcastReceiver和Service的生命周期中的各个函数,产生ANR的上下文不同,导致ANR的原因也会不同;
针对这三个条件,有以下三种情况会触发ANR,详细说明如下。
主线程对输入事件在5秒内没有处理完毕
Android的事件系统从2.3开始做了完全不同的实现,原先2.2中是在Java层实现的,但在2.3中整体转移到了C++层,本书基于2.3以后的版本进行说明。我们先简单了解一下产生这种ANR的整个流程<!-- 在这章之前要先讲Android的事件机制?还是放在后一章讲?偏向于放在后面。 -->。
当应用程序的Window处于Active状态并且能够接收输入事件(例如按键事件、触摸事件等)时,系统底层上报的事件就会被InputDispatcher分发给这个应用程序,应用程序的主线程通过InputChannel读取输入事件并交给界面视图处理,界面视图是一个树状结构,DecorView是视图树的根,事件从树根开始一层一层向端点(例如一个Button)传递。我们通常会注册一个监听器来接收并处理事件,或者创建自定义的视图控件来处理事件。
InputDispatcher运行在系统进程(进程名为system_server)的一个单独的线程中,应用程序的主线程在处理事件的过程中,InputDispatcher会不断的检测处理过程是否超时,一旦超时,会通过一系列的回调通知WMS的notifyANR函数,最终会调用到AMS中mHandler对象里的SHOW_NOT_RESPONDING_MSG这个case,此时界面上就显示系统提示对话框了,同时使用logcat命令查看log(日志信息)也可以看到关于ANR的信息。InputDispatcher就是那个爱打“小报告”的家伙。
一下子出现了好几个重要的名词,要深入了解这种情况的ANR,需要熟悉Android的事件机制,本书会在别的章节中详细分析,这里只需要记住他们的功能:
Window:具体指的是PhoneWindow对象,表示一个能够显示的窗口,它能够接收系统分发的各种输入事件;
InputDispatcher:将系统上报的输入事件分发给当前活动的窗口;
InputChannel:InputDispatcher和应用程序分别运行在两个不同的进程中,InputDispatcher就是通过InputChannel将事件对象传递给应用进程的。
注意:产生这种ANR的前提是要有输入事件,如果用户没有触发任何输入事件,即便是主线程阻塞了,也不会产生ANR,因为InputDispatcher没有分发事件给应用程序,当然也不会检测处理超时和报告ANR了。
主线程在执行BroadcastReceiver的onReceive函数时10秒内没有执行完毕
BroadcastReceiver(简称BR)的onReceive函数运行在主线程中,当这个函数超过10秒钟没有返回就会触发ANR。不过对这种情况的ANR系统不会显示对话框提示,仅是输出log而已。
主线程在执行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(二)
文章都为原创,转载请注明出处,未经允许而盗用者追究法律责任. 很久之前写的了,留着有点浪费,共享之.编写者:李文栋P.S. OpenOffice粘贴过来后格式有些混乱. http://rayleeya ...
- [转发]Android 系统稳定性 - ANR(三)
文章都为原创,转载请注明出处,未经允许而盗用者追究法律责任. 很久之前写的了,留着有点浪费,共享之. 编写者:李文栋 http://rayleeya.iteye.com/blog/1956056 1. ...
- Android 系统稳定性 - ANR(二)(转)
编写者:李文栋P.S. OpenOffice粘贴过来后格式有些混乱. 1.2 如何分析ANR问题 引起ANR问题的根本原因,总的来说可以归纳为两类: 应用进程自身引起的,例如: 主线程阻塞.挂起.死循 ...
- 【原创】Android 系统稳定性 - ANR(二)
文章都为原创,转载请注明出处,未经允许而盗用者追究法律责任. 很久之前写的了,留着有点浪费,共享之.编写者:李文栋P.S. OpenOffice粘贴过来后格式有些混乱. 1.2 如何分析ANR问题 引 ...
- Android 系统稳定性 - ANR(一)
文章都为原创,转载请注明出处,未经允许而盗用者追究法律责任.很久之前写的了,留着有点浪费,共享之.编写者:李文栋 如果你是一个Android应用程序开发人员,你的人生中不可避免的三件事情是:死亡.缴 ...
- [转载]—— Android JNI知识点
Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) 内部运行的 ...
- [转]Android各大网络请求库的比较及实战
自己学习android也有一段时间了,在实际开发中,频繁的接触网络请求,而网络请求的方式很多,最常见的那么几个也就那么几个.本篇文章对常见的网络请求库进行一个总结. HttpUrlConnection ...
- [原创]Mac系统下制作OS 10.11安装镜像
一.所需软件 1.从App Store下载OS X El Capitan 10.11.2 ------------------------------------------------------- ...
- [转]android自动弹出软键盘(输入键盘)
转自:http://www.devdiv.com/home.php?mod=space&uid=65729&do=blog&id=11847 很多应用中对于一个界面比如进入搜索 ...
随机推荐
- House of Spirit(fastbin)
0x01 fastbin fastbin所包含chunk的大小为16 Bytes, 24 Bytes, 32 Bytes, … , 80 Bytes.当分配一块较小的内存(mem<=64 Byt ...
- webuploader项目中多图片上传实例
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- 【Java_基础】Java中Native关键字的作用
本篇博文转载与:Java中Native关键字的作用
- Linux-MySQL基本命令-SQL语句
服务端命令SQL 在数据库系统中,SQL语句不区分大小写(建议用大写) SQL语句可单行或多行书写,以“;”结尾 关键词不能跨多行或简写 用空格和缩进来提高语句的可读性 子句通常位于独立行,便 ...
- 初遇Linux
Ctrl+Alt+(F1-F6):切换虚拟终端 Ctrl+Alt:鼠标切换界面 $:普通用户登录后系统的提示符 #:root用户登录后系统的提示符 Linux命令 exit 用于退出目前的shell ...
- getComputedStyle与currentStyle获取元素当前的css样式
CSS的样式分为三类: 内嵌样式:是写在标签里面的,内嵌样式只对所在的标签有效内部样式:是写在HTML里面的,内部样式只对所在的网页有效外部样式表:如果很多网页需要用到同样的样式,将样式写在一个以.c ...
- CSS3-transform-style
transform-style属性 transform-style属性是3D空间一个重要属性,指定嵌套元素如何在3D空间中呈现.他主要有两个属性值:flat和preserve-3d. transfor ...
- perl学习之正则表达式
9 Perl 中的正则表达式 正则表达式的三种形式 正则表达式中的常用模式 正则表达式的 8 大原则 正则表达式是 Perl 语言的一大特色,也是 Perl 程序中的一点难点,不过如果大家能够很 ...
- Django之url上的include,URL命名和反向解析,命名空间
include其他的URLconfs #At any point, your urlpatterns can “include” other URLconf modules. This #esse ...
- maven 打某一个模块的包
mvn clean mvn clean install -pl benefit-microservice-gateway -am -Dmaven.test.skip=true