Android Anr线上监控

1、ANR执行流程

  • 发生ANR
  • 进程接收异常终止信号,开始写入进程ANR信息
  • 弹出ANR提示框(Rom表现不一,有可能不弹)

2、如何解决ANR 

解决ANR问题,首先要做的是找到问题,线下我们可以通过ADB命令导出ANR文件进行分析,

线上我们可以使用FileObserver或ANR-WatchDog保存ANR堆栈信息,然后上传到服务器。

3、线上监控ANR

方案一:使用FileObserver

线上监控方案我们可以实现FileObserver去监听ANR目录的变化和使用ANR-WatchDod去监听并打印ANR堆栈信息。

优点:

1.基于原生接口调用,时机和内容准确。
2.无性能问题实现简单


缺点:

最大的困难是兼容性问题,这个方案受限于Android系统的SELinux机制,5.0以后基本已经使低权限应用无法监听到trace文件了,但是可以在开发内测阶段通过root手机修改app对应的te文件提权进行监控。Android 7.1.1版本的测试截图

可以看到很多应用都尝试监听ANR文件,但是都被权限拒绝,属于不受信任应用。

SELinux(或SEAndroid)将app划分为主要三种类型(根据user不同,也有其他的domain类型):

1.untrusted_app:第三方app,没有android平台签名,没有system权限
2.platform_app:有android平台签名,没有system权限
3.system_app:有android平台签名和system权限

方案二:使用 BlockCanary

开源的项目BlockCanary,开发者说是用来监控ANR的,不过有个缺点就是它是通过在主线程监控Android生命周期方法执行时间的,即如果方法的执行时间大于阀值,则认为发生了ANR,这种不太准确,因为不同手机系统的ANR时间不一致,阀值的设定不好掌握,而且一旦发生了ANR,监控方法就无法收到方法结束时间,无法监控到。

方案三:使用 ANR-WatchDog

ANR-WatchDog
 Git地址:ANR-WatchDog
 ANR-WatchDog是一个非侵入式的ANR监控组件。

Watchdog机制总结:
每一个线程都可以对应一个Looper,一个Looper对应一个MessageQueue,所以可以通过向MessageQueue中post检测任务来预测该检测任务是否被及时的执行,以此达到检测线程任务卡顿的效果,但是前提是该线程要先创建一个Looper
Watchdog必须独自运行在一个单独的线程中,这样才可以监控其他线程而不互相影响
使用Watchdog机制来实现在线的anr监控可能并不能百分百准确,比如5秒发生anr,在快到5秒的临界值的时候耗时任务正好执行完成了,这时候执行anr检测任务,在检测任务执行过程中,有可能Watchdog线程wait的时间也到了,这时候发现检测任务还没执行完于是就报了一个anr,这是不准确的;另一种情况可能是5秒anr已经发生了,但是Watchdog线程检测还没还是wait,也就是anr发生的时间和Watchdog线程wait的时间错开了,等到下一次Watchdog线程开始wait的时候,anr已经发生完了,主线程可能已经恢复正常,这时候就会漏掉这次发生的anr信息搜集,所以当anr卡顿的时间是Watchdog线程wait时间的两倍的时候,才能完整的扫描到anr并记录,也就是说Watchdog的wait时间为2.5秒,这个在实际应用中有点过于频繁了,如果设备不休眠,Watchdog相当于每间隔2.5秒就会运行一下,可能会有耗电风险

总结

 ANR异常我们可分为线上监测和线下监测两个方向

  • 线上监测主要是利用FileObserver进行ANR目录文件变化监听,以ANR-WatchDog进行补充。
  • FileObserver在使用过程中应注意高版本程序不可用以及预防死锁出现。
  • 线下监测主要是在报错之后利用ADB命令将错误的日志导出并找到错误的类进行分析。

猜你喜欢

转载自blog.csdn.net/cpcpcp123/article/details/121823631