APP应用ANR

一:ANR是什么

ANR:应用程序无响应(Application Not Responding)

系统ActivityManagerService与WindowManagerService会检测应用程序的响应时间。如果主线程主线程(UI线程)在超时时间内对Input事件(按键、触屏等)或者特定操作(Broadcast、service的各种生命周期方法)没有处理完毕,就会出现ANR。

  1. InputDispatchingTimeOut:Input事件分发超时,超时时间:5s。
  2. BroadcastTimeOut:广播生命周期方法执行超时:前台广播10s,后台广播60s,只有有序广播才可能出现该场景
  3. ServiceTimeOut:Service生命周期方法执行超时:前台Service20s,后台Service200s。

二:为什么会ANR

  1. InputDispatcherTimeOut

  1. BroadcastTimeOut

  1. serviceTimeOut

三:怎么定位ANR

  1. 获取日志

分析ANR主要依靠traces日志或者DropBox日志,一般稳定平台收集的日志都包含。

  1. trace.txt日志:原生ROM只有一个trace.txt,新的ANR会覆盖之前的日志(data/anr)
  2. DropBox日志:Android2.2开始增加了DropBox功能,保留3天内发生的所有ANR日志。DropBox日志实际包含了trace.txt所有信息,此外还提供了ANR的超时原因及详细的CPU的使用信息,因此建议直接使用该日志。(data/system/dropbox)
  1. 确认超时类型

超时类型可以在DropBox日志的开头部分找到。这部分实际包含了发生ANR的位置、进程以及最重要的超时类型、超时原因等信息

  1. 检查CPU、IO及内存

DropBox日志这部分包含了,发生ANR时间点之前一段时间的CPU、IO、内存以及GC的统计信息。

如果CPU使用量过低,说明主线程被阻塞,检查是否在主线程有等待操作。

如果CPU使用量接近100%,说明系统很忙,有可能主线程在进行大量计算,比如出现了死循环。

如果IO wait过高,可能主程序在进行读写操作。

如果内存可用量过低,Heap free很小,这种可能是出现内存泄漏,或者有其他进程占用了大量资源,这种一般是出现OOM,但是也可能会导致ANR

  1. 检查线程堆栈信息

DripBox日志中会打印所有的进程及线程,发生ANR的进程一般打印在最上面,优选关注该进程的UI线程,一般名字是“main”,最准确的判断方法是sysTid与PID相等的为UI线程。

四:如何避免ANR

  1. UI线程耗时操作异步处理:线程池、HandlerThread、AsyncTask、IntentService、注册广播时指定线程
  2. 非UI线程如果有太耗时资源的操作,要考虑对UI线程的影响
  3. 关注是否会互锁、死循环
  4. 异步转同步操作慎用,必须有超时时间。主线程调用AIDL接口时禁止异步转同步,AIDL的onServiceConnected必然回主线
  5. SDK开放的API,尽量加上UIThread、WorkerThread、AnyThread注解,防止调用方法用错。

五:总结

Crash和ANR是android开发永恒的话题,上述的介绍其实也更多是知识搬运。实际过程的问题肯定比介绍的复杂多 ,而且往往都需要结合业务的逻辑代码,才可能找到方向,直至解决。

因此,我觉得我们能做的两点:

一是不断的加强自己的敏感度,把规范作为习惯,将问题消灭在萌芽阶段。

另一点是丰富自己的积累,这样面对这些问题时,才会更有方法,也更有底气。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值