Android的日志收集主要包括JVM崩溃、Native崩溃、ANR三大类,本文主要是讨论ANR的日志。
一、造成ANR的场景
- InputDispatching Timeout: 输入事件 5s 未处理完成,包括按键和触摸事件;日志关键字:InputDispatching Timeout
- Service Timeout: 前台服务 20s 未处理完成,后台服务 200s 未处理完成;日志关键字:Timeout executing service
- BroadcastQueue Timeout:前台广播 10s 未处理完成,后台广播 60s 未处理完成;日志关键字:Timeout of broadcast BroadcastRecord
- ContentProvider Timeout:内容提供者 10s 未处理完成;日志关键字:Timeout publishing content providers
二、线下ANR日志
当ANR发生时,早期的Android系统会记录到 data/anr/
目录中,我们线下可以导出此文件,分析ANR的原因。
旧一点的系统会记录到 data/anr/traces.txt
文件,由于多次出现ANR会有覆盖的文件,所以产商优化之后会根据时间记录每次ANR。
比如在 Android 9
查看ANR文件
1 | $ adb shell ls /data/anr/ |
这里提示没有权限导出ANR文件,所以这需要有root权限,但Android是支持我们导出日志的,通过另外一个命令:
1 | $ adb bugreport |
执行命令后,需要等待一段时间,Android会打包所有日志,导出的是一个zip压缩包,ANR文件在 \FS\data\anr
目录。
如何解析ANR日志,请参考【ANR问题简析】
其实也会有漏记录的情况
三、线上ANR日志
上面是线下的情况,线上由于权限的问题App是不能读取 data/anr
目录的文件,这时可以集成第三方的SDK来实现对ANR监控和日志收集,第三方SDK都是通过一些骚操作来实现日志的收集,有兴趣可以阅读相关文章。
举个简单的例子:【ANRWatchDog
】 是一个自动检测ANR的开源库,它只有两个源文件 ANRError.java
和 ANRWatchDog.java
。
原理就是:
- 启动一个监控线程,5秒一次循环;
- 每次循环往主线程post一个runnable,修改一个变量值;
- 下次循环检查变量的值有没有被修改,如果没有,则主线程卡顿了至少5秒(肯定会存在误差);
- 输出线程堆栈信息。
四、第三方SDK
第三方的SDK很多,这里只列出几个。
注意:这种SDK不要在一个App里集成多个,可能会冲突导致捕捉不到日志。
1. BreakPad
Google公司开发的开源多平台C++崩溃检测库。Breakpad可以捕获发布给用户的应用程序的崩溃,并记录软件崩溃的调试信息到“minidump”文件中。调试信息包括错误行号,报错详情,堆栈错误(stack traces)。软件崩溃时候把生成的“minidump”上传到自己的服务器上就可已方便的获取足够细致崩溃详情。
minidump是由微软开发的崩溃记录文件格式。minidump为二进制文件,体积小。为了保持统一,breakpad在其他系统下也选择生成minidump文件。
评:没用过,看起来很复杂的样子。
2. XCrash
XCrash
是 “爱奇艺” 开源的日志收集库,能为 Android App 提供捕获 java 崩溃
,native 崩溃
和 ANR
的能力。不需要 root 权限或任何系统权限。XCrash
能在 app 进程崩溃
或 ANR
时,在你指定的目录中生成一个 tombstone
文件(格式与安卓系统的 tombstone
文件类似)。
评:捕获能力很好,此项目官方一直有维护,适合有自己的日志后台的团队,通过抓取奔溃和ANR日志上传到自己的服务器,自由度很高。
3. Bugly
腾讯Bugly,为移动开发者提供专业的异常上报和运营统计,支持崩溃日志分析、ANR分析、数据统计分析等。
评:只要用QQ账号登录就可以集成SDK,ANR和崩溃日志捕获能力很好,自动上报,提供后台查看日志。集成度很高,一条龙服务,算是比较成熟的产品,开发者集成它的SDK也简单。就是对用户的隐私数据收集的比较多,新版本(v4.0.4)应该有所改善。
4. 华为AGC
这是华为生态服务里的一个产品,可以收集崩溃日志和ANR。
评:和Bugly相似,集成SDK后自动上报,支持崩溃日志和ANR,目前只集成,要一段时间才看到效果。另外它有一个门槛,就是需要华为开发者才能使用,这是毋庸置疑的。如果你需要集成华为的产商推送HMS,那么可以顺便把这个服务加上去。