Android进阶

Android ANR 监测方案解析

2020-03-28  本文已影响0人  奶盖ww

前言

ANR(Application Not Responding),应用程序无响应,会严重影响用户体验。作为测试开发人员更深入的理解ANR原理,可以更好的针对各类卡顿性能问题制定对应的监控策略。本文简单总结了Android系统的ANR监测与现有的监测方案的原理对比。

ANR的触发条件

ANR的本质是一个性能问题,即主线程中的耗时操作造成主线程堵塞,导致应用失去响应能力。常见的超时时限:

Service与Bradcast只会打印trace信息,不会提示用户ANR弹窗,大部分可感知的ANR都是由于InputEvent。

Android对ANR的监控机制

Android应用程序是通过消息来驱动的,Android某种意义上也可以说成是一个以消息驱动的系统,UI、事件、生命周期都和消息处理机制息息相关。Android的ANR监测方案也是一样,大部分就是利用了Android的消息机制。

InputEvent的ANR与上图有些许不同,是在Native监控,但同样会堵塞主线程的消息队列,后面会讲到一部分监测场景。

应用ANR检测方案

目前流行的ANR检测方案有开源的BlockCanary 、ANR-WatchDog、SafeLooper, 还有根据谷歌原生系统接口监测的方案:FileObserver。下面就针对这四种方案根据场景解析对比。

BlockCanary

BlockCanary是国内开发者markzhai开发的一款非侵入式的轻量性能监控组件,在Github上有接近4000 star。原理巧妙的利用了Android原生Looper.loop中的一个log打印逻辑。

这个log打印逻辑正是在Message消息分发前后,大部分的性能卡顿问题都是在这里发生的,监控这两个逻辑之间的时间差就可以得到当前主线程的卡顿状态,如果超时则获取trace信息并上报。具体实现:

ANR-WatchDog

ANR-WatchDog是参考Android WatchDog机制(com.android.server.WatchDog.java)起个单独线程向主线程发送一个变量+1操作,自我休眠自定义ANR的阈值,休眠过后判断变量是否+1完成,如果未完成则告警。

SafeLooper

SafeLooper是个比较新奇的思路,本身就是一个堵塞的消息,在自己内部进行消息的处理,通过反射接管主线程Looper的功能。

此方案使用反射进行message管理会有很大的性能损耗,但可以自由定制,这种AOP的思想是可以借鉴的。

FileObserver

有ANR的流程就可以知道/data/anr文件夹的变化代表着ANR的发生,AMS在dumpStackTrace方法中给了我们一些提示。

按照这个思路,当ANR发生的时候,我们是可以通过监听该文件的写入情况来判断是否发生了ANR,看起来这是一个不错的时机。需要注意的是,所有应用发生ANR的时候都会进行回调,因此需要做一些过滤与判断,如包名、进程号等。ANR生成的trace如图:

总结

本文汇总了目前主流的ANR监测方案的原理和实现,目前能了解到的方案并不太多,在Goolge Play上有2.68%实用率的ACRA库也只是推荐了WatchDog方式。建议 FileObserver和watchDog组合使用,能覆盖绝大部分的机型和ANR异常。如果其他同学有更好的建议和方案欢迎交流,共同进步。

参考文献

https://github.com/ACRA/acra
https://github.com/markzhai/AndroidPerformanceMonitor
https://github.com/SalomonBrys/ANR-WatchDog
http://gityuan.com/2016/07/02/android-anr/
http://blog.csdn.net/zhudaozhuan/article/details/50964832

上一篇下一篇

猜你喜欢

热点阅读