欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android如何分析排查ANR

程序员文章站 2022-07-14 17:20:03
...

在Android开发中,当程序发生异常时会抛出异常信息,先说下三种常见类型:

  • 列表内容KeyDispatchTimeout(谷歌default 5s,MTK平台上是8s) –主要类型
    按键或触摸事件在特定时间内无响应
  • BroadcastTimeout(10s)
    BroadcastReceiver在特定时间内无法处理完成
  • ServiceTimeout(20s) –小概率类型
    Service在特定的时间内无法处理完成

一些典型的ANR 问题场景

1)最常见错误,UI线程等待其它线程释放某个锁,导致UI线程无法处理用户输入;

2)游戏中每帧动画都进行了比较耗时的大量计算,导致CPU忙不过来;

3)Web应用中,网络状态不稳定,而界面在等待网络数据;

4)UI线程中进行了一些磁盘IO(包括数据库、SD卡等等)的操作,在个别设备上因为硬件损坏等原因阻塞住了;

5)手机被其他App占用着CPU,自己获取不到足够的CPU 时间片,纯属误伤。

排查分析的思路:

1、通过ANR 日志定位问题

当ANR发生时,我们往往通过Logcat和traces文件(目录/data/anr/)的相关信息输出去定位问题。主要包含以下几方面:

1)基本信息,包括进程名、进程号、包名、系统build号、ANR 类型等等;

2)CPU使用信息,包括活跃进程的CPU 平均占用率、IO情况等等;

3)线程堆栈信息,所属进程包括发生ANR的进程、其父进程、最近有活动的3个进程等等。

1.1首先通过Log来获取异常信息

android系统会自动帮我们生成一个log日志输出文件,在data/system/dropbox/下,真机测试需要root权限,模拟器在DDMS下可以查看。

用这种方法,出现问题,根本不需要断点调试 , 直接定位到问题,屡试不爽 。
从LOG可以看出ANR的类型,CPU的使用情况,

一般在如下几种情况会产生log 。

1,程序异常退出 , uncaused exception
2,程序强制关闭 ,Force Closed (简称FC)
3,程序无响应 , Application No Response (简称ANR) , 顺便,一般主线程超过5秒么有处理就会ANR

步骤:

1.打开log文件 , 由于是ANR错误,因此搜索”ANR ” , 为何要加空格呢,你加上和去掉比较一下就知道了 。 可以屏蔽掉不少保存到anr.log文件的无效信息

定位到关键的事件信息如下:

01-15 16:49:02.433 E/ActivityManager( 2466): ANR in com.android.mms (com.android.mms/.ui.SlideshowActivity)
01-15 16:49:02.433 E/ActivityManager( 2466): Reason: keyDispatchingTimedOut
01-15 16:49:02.433 E/ActivityManager( 2466): Load: 0.6 / 0.61 / 0.42
01-15 16:49:02.433 E/ActivityManager( 2466): CPU usage from 1337225ms to 57ms ago:
01-15 16:49:02.433 E/ActivityManager( 2466):   sensorserver_ya: 8% = 0% user + 8% kernel / faults: 40 minor
......
01-15 16:49:02.433 E/ActivityManager( 2466):  -com.android.mms: 0% = 0% user + 0% kernel
01-15 16:49:02.433 E/ActivityManager( 2466):  -flush-179:8: 0% = 0% user + 0% kernel
01-15 16:49:02.433 E/ActivityManager( 2466): TOTAL: 25% = 10% user + 14% kernel + 0% iowait + 0% irq + 0% softirq
01-15 16:49:02.436 I/        ( 2466): dumpmesg > "/data/log/dumpstate_app_anr.log"

我们用自然语言来描述一下日志,

01-15 16:49:02.433 E/ActivityManager( 2466): ANR in com.android.mms (com.android.mms/.ui.SlideshowActivity)

翻译:在16:49分2秒433毫秒的时候 ActivityManager (进程号为2466) 发生了如下错误:com.android.mms包下面的.ui.SlideshowActivity 无响应 。

01-15 16:49:02.433 E/ActivityManager( 2466): Reason: keyDispatchingTimedOut

翻译:原因 , keyDispatchingTimeOut - 按键分配超时

01-15 16:49:02.433 E/ActivityManager( 2466): Load: 0.6 / 0.61 / 0.42

翻译:5分钟,10分钟,15分钟内的平均负载分别为:0.6 , 0.61 , 0.42

我们大概知道问题是什么了,问题是在点击按钮某时候可能处理不过来按钮事件,导致超时无响应 。但我们不能准确的知道到底问题在哪儿 , 只是猜测 ,比如这个应用程序中,多个IO操作的地方都在主线程中,可能引起问题,但不好判断到底是哪个 ,所以我们目前掌握的信息还不够 。
于是我们再分析虚拟机信息 ,搜索“Dalvik Thread”关键词,快速定位到本应用程序的虚拟机信息日志

1.2通过分析trace文件得到ANR信息(真机导出,模拟机在DDMS下查看)

如果ANR发生,对应的应用会收到SIGQUIT异常终止信号,dalvik虚拟机就会自动在/data/anr/目录下生成trace.txt文件,将异常信息写入到traces文件中,系统会记录异常的位置、CPU和内存当时的使用情况,通过查看日志基本就能判断问题所在。

接下来用adb shell命令导出该文件,通过shell命令就可以了。

adb pull /data/anr/traces.txt d:/ =》意思是将手机上的traces.txt导出到电脑的d目录下
或者
1、adb shell
2、cat /data/anr/xxx >/mnt/sdcard/yy/zz.txt
3、exit
4、adb pull /mnt/sdcard/yy/zz.txt d: ,即可将文件导出到了d盘。

在发生ANR时,

步骤:
1. 找到ANR关键字(大写匹配)
2. 向上查找timeout关键字,这个时候能找到ANR的原因,如: Application do too much work in main thread 等。
3. 查看trace 文件找出出现的最终原因。

测试过程发现ANR的现状

1、在平常测试中,ANR基本测试不到,因为ANR基本发生在垃圾设备中,弱网络,频繁操作。
2、问题不必现,即使看到了问题,定位麻烦:要去data/anr.txt 文件里面查找。必须root,没有对应关系,分析复杂,导出文件就必须依赖手机零距离。
由于anr问题不必现,因此引入以下ANR检测工具,当anr问题出现时,自动dump手机中的日志信息如trace文件、堆栈信息
基本原理

检测到UI主线程卡顿时间超过设定的时间,如4s,即dump trace文件以及堆栈信息,同时抛出异常,收集信息,根据这些文件信息即可定位到发生anr的原因

1.3在源代码中插入ANR检测工具(BlockCanary、StrictMode)

根据提示找到来找到原因,
更多参考:blockcanaryBlockCanary解析strictMode

1.4使用第三方SDK输出Crach信息到后台服务器:

如腾讯bugly 和umeng