码迷,mamicode.com
首页 > 其他好文 > 详细

ANR一般性分析方法

时间:2016-05-27 18:09:22      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:

Android项目的ANR问题经常让开发者困扰。究其原因,有些ANR问题很难定位。
若ANR和普通crash一样,打出耗时操作的调用栈,那么想办法修复就好了。
最近项目中的ANR问题较为严重,相信每个快速膨胀的app都会经历这个时刻,总结一些经验供大家参考。
 
ANR原因
ANR是耗时操作造成。
若有A/B/C事件串行执行于UI线程,当C事件发生ANR时,说明A->B->C太耗时了,并不能确定耗时操作在哪个具体事件上。
 
ANR基本定位
ANR的有用信息,我们需要在trace文件中获取。
trace文件路径:data\anr\traces_packageName.txt
在trace文件中,我们能够看到如下信息
技术分享
DALVIK THREAD(14)表明trace文件中收集了14个线程的信息与调用栈。
下面的"main"指的是主线程,我们分析"main"所在的片段即可定位ANR。
图中所示,调用栈指向了com.puff.test.MainActivity.onResume方法,这就是ANR发生的原因,调用到onResume方法时,超时了!
 
ANR定位不准
当跟随调用栈查看onResume方法时,我们发现唯一的操作便是耗时操作
技术分享
onResume阻塞了2s,造成了ANR。但是Activity的超时需要5s未响应,看来ANR的原因不仅仅是onResume造成的。
我们继续跟踪onResume之前调用的onCreate与onStart
技术分享  技术分享
所以根据trace文件定位ANR未必能准确,trace只给出了造成ANR的直接原因,间接原因仍然需要分析。
 
ANR辅助定位——BlockCanary
通过trace文件能够确定发生ANR的位置,但只是压死骆驼的最后一根稻草。
而BlockCanary工具却能统计到过程中所有耗时操作(耗时阈值由自己设置)。
技术分享
 
原理比较简单,通过替换Looper的Printer达到计算msg处理的耗时。
同时也提供了一些很有帮助的参数,譬如总耗时与线程耗时,可用内存等。
具体内容可详见 BlockCanary
 
ANR辅助定位——埋点
通过trace文件与BlockCanary工具基本上可以定位耗时操作了,不过仍然有些情况会让人困扰。
若query(*,*)是耗时操作,在onStart中调用了多次,造成了onResume产生ANR,那么虽然能定位query是耗时操作,却不能确定是哪个操作真正耗时。
方法内多次调用同一耗时操作,那么就果断埋点吧!
通过埋点统计操作用时,即可更准确定位耗时操作。
 
多次采样确定ANR耗时操作
ANR不好复现,耗时操作的耗时也不稳定,通过多次采样来确定耗时操作似乎已经是通用方案了。
若是层级较深或复杂操作才能触发耗时操作的,推荐使用iTestin工具进行自动化测试。
iTestin工具的功能非常丰富,常用的操作都可以通过iTestin来模拟进行,更多的内容就阅读文档吧http://i.testin.cn/
若是比较简单的操作,可以直接通过adb的shell命令进行自动化测试了。
譬如上例中onResume经常发生ANR,那么多次启动并关闭就可以多次采样了。
adb shell am start com.puff.test/com.puff.test.MainActivity
adb shell am kill com.puff.test
便可执行启动与关闭页面,我们再循环执行一定次数就可以采样了。

ANR一般性分析方法

标签:

原文地址:http://www.cnblogs.com/puff/p/5535436.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!