什么是ANR

ANR:Application Not Responding,即应用程序无响应。

在Android中,ActivityManagerService(简称AMS)和WindowManagerService(简称WMS)会监测应用程序的响应时间,如果应用程序主线程(即UI线程)在超时时间内对输入事件没有处理完毕,或者对特定操作没有执行完毕,就会出现ANR。

对于输入事件没有处理完毕产生的ANR,Android会显示一个对话框,提示用户当前应用程序没有响应,用户可以选择继续等待或者关闭这个应用程序(也就是杀掉这个应用程序的进程)。

为什么会产生ANR

ANR一般有三种类型:

  1. 输入事件(按键和触摸事件)5s内没被处理:Input event dispatching timed out
  2. BroadcastReceiver的事件(onRecieve方法)在规定时间内没处理完(前台广播为10s,后台广播为60s):Timeout of broadcast BroadcastRecord
  3. Service前台20s后台200s未完成启动:Timeout executing service
  4. ContentProvider的publish在10s内没进行完:timeout publishing content providers

ANR产生的常见原因:

  1. 主线程(UI线程)在做一些阻塞耗时的工作。例如文件读写,数据库读写,网络查询等。
  2. 主线程被其他线程锁。
  3. cpu被其他进程占用,该进程没被分配到足够的cpu资源。

如何分析ANR

从log中找到ANR发生的信息

可以从log中搜索“ANR in”或“am_anr”,会找到ANR发生的log,该行会包含了ANR的时间、进程、是何种ANR等信息。

分析ANR产生的trace文件

ANR产生时,系统会生成一个traces.txt的文件放在/data/anr/下。 可以通过adb命令将其导出到本地:
adb pull data/anr/traces.txt

trace文件记录了发生ANR前后该进程的各个线程的stack。

分析思路
  1. 普通阻塞导致的ANR。
  2. 如果是BroadcastReceiver的ANR可以怀疑BroadCastReceiver.onRecieve()的问题,如果的Service或Provider就怀疑是否其onCreate()的问题。
  3. 如果某些进程的CPU占用百分比较高,几乎占用了所有CPU资源,而发生ANR的进程CPU占用为0%或非常低,则认为CPU资源被占用,进程没有被分配足够的资源,从而发生了ANR。这种情况多数可以认为是系统状态的问题,并不是由本应用造成的。
  4. 如果CPU使用量很少,说明主线程被BLOCK了,可能是主进程被锁。
  5. 如果IOwait很高,说明ANR有可能是主线程在进行I/O操作造成的。
  6. 如果CPU使用量接近100%,说明CPU满负荷,有可能是CPU饥饿导致了ANR。
  7. 内存原因。

如何避免ANR

1.合理使用UI主线程,耗时操作放入其他线程工作。

1.1 UI线程尽量只做跟UI相关的工作。

1.2 耗时的工作(比如数据库操作,I/O,连接网络或者别的有可能阻碍UI线程的操作)把它放入单独的线程处理。

2.尽量用Handler来处理UI thread和别的thread之间的交互。

3.合理使用并遵循Android生命周期,避免在onCreate()和onResume()做过多的事情。

4.sharedPreference的使用:

4.1 sharedPreference的commit()方法是同步的,apply()方法一般是异步执行的。在主线程不要用其commit(),用apply()替换。

4.2 sharedPreference的写是全量写而非增量写,所以尽量都修改完同一apply,避免改一点apply一次(apply()方法在Activity stop的时候主线程会等待写入完成,提交多次就很容易卡)。并且存储文本也不宜过大,这样会很慢。另外,如果写入的是json或者xml,由于需要加和删转义符号,速度会比较慢。

5.如果主线程阻塞,开辟单独的子线程来处理耗时阻塞事务。

6.如果I/O阻塞,一般来说就是文件读写或数据库操作执行在主线程了,可以通过开辟子线程的方式异步执行。

7.如果内存不够用,增大VM内存,使用largeHeap属性,排查内存泄露。

拓展

哪些地方是执行在主线程的

各个组件的生命周期函数都不应该有太耗时的操作。

Activity的所有生命周期回调、Service的onCreate()、BroadcastReceiver的onReceive(开个IntentService去执行相应操作)、
ContentProvider的onCreate()是执行在主线程的。

没有使用子线程的looper的Handler的handleMessage,
post(Runnable)是执行在主线程的。

AsyncTask的回调中除了doInBackground,其他都是执行在主线程的。

View的post(Runnable)是执行在主线程的。

尽量避免主线程的被锁的情况。

一些同步的操作主线程有可能被锁,需要等待其他线程释放相应锁才能继续执行,这样会有一定的ANR风险。对于这种情况有时也可以用异步线程来执行相应的逻辑。另外, 我们要避免死锁的发生(主线程被死锁基本就等于要发生ANR了)。

Android探究之ANR的更多相关文章

  1. Android 系统稳定性 - ANR(二)(转)

    编写者:李文栋P.S. OpenOffice粘贴过来后格式有些混乱. 1.2 如何分析ANR问题 引起ANR问题的根本原因,总的来说可以归纳为两类: 应用进程自身引起的,例如: 主线程阻塞.挂起.死循 ...

  2. 【原创】Android 系统稳定性 - ANR(二)

    文章都为原创,转载请注明出处,未经允许而盗用者追究法律责任. 很久之前写的了,留着有点浪费,共享之.编写者:李文栋P.S. OpenOffice粘贴过来后格式有些混乱. 1.2 如何分析ANR问题 引 ...

  3. [转发]Android 系统稳定性 - ANR(二)

    文章都为原创,转载请注明出处,未经允许而盗用者追究法律责任. 很久之前写的了,留着有点浪费,共享之.编写者:李文栋P.S. OpenOffice粘贴过来后格式有些混乱. http://rayleeya ...

  4. Android中的ANR

    有过Android开发经历的人都不会对ANR陌生,它和崩溃一样是程序设计的问题.本文将以较为深入的视角来介绍什么是ANR,出现场景,如何避免以及如何定位分析ANR,希望可以帮助大家在编写程序时有所帮助 ...

  5. 【Android】[转] ANR的分析和问题处理

    一:什么是ANR ANR:Application Not Responding,即应用无响应 二:ANR的类型 ANR一般有三种类型: 1. KeyDispatchTimeout(5 seconds) ...

  6. android应用程序ANR定义

    在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:Application Not Responding)对话框.用户可以选择 ...

  7. Android 系统稳定性 - ANR(一)

    文章都为原创,转载请注明出处,未经允许而盗用者追究法律责任.很久之前写的了,留着有点浪费,共享之.编写者:李文栋  如果你是一个Android应用程序开发人员,你的人生中不可避免的三件事情是:死亡.缴 ...

  8. 如何避免Android程序的ANR?

    In Android, the system guards against applications that are insufficiently responsive for a period o ...

  9. [转发]Android 系统稳定性 - ANR(三)

    文章都为原创,转载请注明出处,未经允许而盗用者追究法律责任. 很久之前写的了,留着有点浪费,共享之. 编写者:李文栋 http://rayleeya.iteye.com/blog/1956056 1. ...

随机推荐

  1. 移动端布局方案汇总&&原理解析

    阿里flexible布局 - 版本1.x 该布局于 2017年8月9日被2.0版本取代 实现原理 假设(UI稿750px宽) 设置viewport的 scale = 1/window.devicePi ...

  2. SQLServer多表联查,多表分页查询

    多表联查: select p.*,s.Sheng , i.Shifrom  [dbo].[ProductRecordInfo]   --表名 p left join [ShengInfo] s on ...

  3. libaio.so.1()(64bit) is needed by MySQL-server 问题解决办法

    [root@localhost upload]# rpm -ivh MySQL-server-5.5.25a-1.rhel5.x86_64.rpmerror: Failed dependencies: ...

  4. 《iOS 11 安全区域适配总结》

    本文来自于腾讯Bugly公众号(weixinBugly),作者:sonialiu,未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/W1_0VrchCO50owhJ ...

  5. Quartz+ssm注解方式的最最最最简单使用

    Maven配置 <!-- quartz监控 --> <dependency> <groupId>org.quartz-scheduler</groupId&g ...

  6. v-cloak的用法和注意事项

    v-cloak是前端框架vue.js中的一个方法,作用是为了防止在页面加载时先出现变量名闪烁的情况,造成不好的用户体验, 例如:{{ v.name}} (闪一下)=> 张三 用法:html中:& ...

  7. java集合常见面试题

    1. Array和ArrayList的区别,什么时候更合适用Array a)      Array是数组,可以容纳基本类型和对象,而ArrayList是集合,只能容纳对象 b)      Array是 ...

  8. Linux篇---ftp服务器的搭建

    一.前述 企业中linux搭建ftp服务器还是很实用的,所以本文针对centoos7和centoos6搭建服务器教程做个总结. 二.具体 1.显示如下图则表示已安装 vsftp软件.如果未显示则需要安 ...

  9. 关于Python深浅拷贝

    拷贝: 说明:原则上就是把数据分离出来,复制其数据,并以后修改互不影响. 何来深浅拷贝的说法? 深浅拷贝的“深”和“浅”可以理解为从变量到硬盘上的物理存储介质之间的层次的多少. 下面用一个示例来解释浅 ...

  10. 一次 HashSet 所引起的并发问题

    背景 上午刚到公司,准备开始一天的摸鱼之旅时突然收到了一封监控中心的邮件. 心中暗道不好,因为监控系统从来不会告诉我应用完美无 bug,其实系统挺猥琐. 打开邮件一看,果然告知我有一个应用的线程池队列 ...