ANR(应用程序无响应)是Android系统中一种常见的问题,当应用的主线程因被阻塞而无法在规定时间内响应用户操作或系统事件时,系统会弹出ANR对话框,严重影响用户体验和应用的稳定性。
🔍 ANR的触发条件
系统对不同类型的操作有着严格的超时限制:
| 触发条件类型 | 描述 | 超时时间 |
|---|---|---|
| InputDispatching Timeout | 应用在5秒内未响应屏幕触摸或按键事件。 | 5秒 |
| BroadcastQueue Timeout | 前台广播的onReceive()方法在10秒内未执行完毕。 | 前台10秒,后台60秒 |
| Service Timeout | 前台服务未在规定时间内执行完毕。 | 前台20秒,后台200秒 |
| ContentProvider Timeout | ContentProvider在发布时未在规定时间内完成。 | 10秒 |
1.输入事件分发超时
图片来自《安卓性能优化之道》
如果在超时时间内没有收到对应的窗口或程序的消费结果,InputDispatcher便会认为窗口 或应用无响应,从而触发“InputDispatching TimedOut”错误。
图片来自《安卓性能优化之道》
InputDispatcher在分发事件时,会判断waitQueue中是否有5s未被移除的,如果有则认为发生了ANR。
2.广播接收超时
在普通广播,有序广播,粘性广播中,只有有序广播会产生ANR,因为该广播是同步的。
在启动广播时,会启动ANR延时任务,当onReciver函数执行完以后,会移除ANR延时任务。如果在此期间执行耗时超过10s,就会触发ANR。
3.服务启动超时
和广播原理类似,也是启动一个ANR延时任务进行判断。
4.contentProvider超时
AMS在调用目标程序的bindApplication方法之前,会先向 Handler发送CONTENT_PROVIDER_PUBLISH_TIMEOUT的延时任务,当目标程序在bindApplication方法中发布完ContentProvider后,便会 通知AMS移除该任务消息。
排查和定位,可以通过分析trace.txt 日志。配合第三方Matrix,Bugly,ANR_watchdog使用。