Android ANR检测

Android ANR检测,第1张

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

用户触摸 *** 作InputEvent:5s内无响应触发ANR提示;

广播Broadcast:前台广播10s和后台广播60s会触发ANR;

服务Service:前台进程Service20s和后台进程Service200s会触发ANR;

而Service和Broadcast只会打印trace信息,不会提示用户ANRd窗,大部分可感知的ANR都是由于InputEvent引起的。

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

InputEvent的ANR与上图有些不同,是在Native监控,但同样会堵塞主线程的消息队列。

一般来说有四种,分别为BlockCanay、ANR-WatchDog、SafeLooper和FileObserver。

BlockCanary一种非侵入式的轻量性能监控组件,原理巧妙的利用了Android原生Looper.loop中的一个log打印逻辑

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

它的思路是开辟一个单独现场向主线程发送一个变量+1 *** 作,自我休眠自定义ANR的阈值,休眠过后判断变量是否+1完成,如果未完成则警告。

它主要是通过反射接管主线程Looper的功能,可以自由定制,但是进行message管理会有很大的性能损耗。

Android手机发生ANR后,会把信息存储在/data/anr/traces.txt文件,我们只需要监听这个文件的变化就可以知道是否发生了ANR。

在Android里,应用程序的响应性是由Activity Manager和WindowManager系统服务监视的 。当它监测到以下情况中的一个时,Android就会针对特定的应用程序显示ANR:

在5秒内没有响应输入的事件(例如,按键按下,屏幕触摸)

.BroadcastReceiver在10秒内没有执行完毕避免方法:

 1、运行在主线程里的任何方法都尽可能少做事情。特别是,Activity应该在它的关键生命周期方法(如onCreate()和onResume())里尽可能少的去做创建 *** 作。(可以采用重新开启子线程的方式,然后使用Handler+Message的方式做一些 *** 作,比如更新主线程中的ui等) 2、应用程序应该避免在BroadcastReceiver里做耗时的 *** 作或计算。但不再是在子线程里做这些任务(因为 BroadcastReceiver的生命周期短),替代的是,如果响应Intent广播需要执行一个耗时的动作的话,应用程序应该启动一个 Service。(此处需要注意的是可以在广播接受者中启动Service,但是却不可以在Service中启动broadcasereciver) 3、避免在Intent Receiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。如果你的应用程序在响应Intent广 播时需要向用户展示什么,你应该使用Notification Manager来实现。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11827152.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-19
下一篇 2023-05-19

发表评论

登录后才能评论

评论列表(0条)

保存