3. ANR的触发机制与阈值归纳总结

ANR 这个词,干 Android 的没人不认识。说白了就是「应用无响应」——你的 App 卡住了,系统弹个对话框问用户「等还是关」。但你真的清楚它到底怎么触发的吗?阈值又分别是多少?我在项目里排查过好几次 ANR,发现很多人连基础阈值都记混。今天咱们就捋清楚。

触发机制:谁在盯着你?

系统里有个叫 ServiceManager 的看门狗,但不是它直接触发 ANR。真正干活的是一组 Watchdog 线程和 AMS(Activity Manager Service)。它们给主线程发一条消息,然后开始倒计时——

  • 如果主线程在规定时间内处理完消息,平安无事。
  • 如果超时还没处理完 → 系统认为线程被堵死了 → 弹出 ANR 对话框。

嗯,这里要注意:不是只有主线程做耗时操作才触发。比如 BroadcastReceiver 在 onReceive 里跑网络请求,或者 Service 在 onStartCommand 里循环计算——只要超时,一样会挂。

核心结论: ANR 本质上是「系统设定了一个 deadline,执行方没赶在 deadline 前交出结果」。

阈值清单:分别多少毫秒?

我把不同组件的阈值整理成了表。我自己经常拿来贴在工位上——记不住就翻。

组件 / 场景 超时阈值 (Android Q+ 默认) 说明
BroadcastReceiver (前台) 10 秒 从 onReceive 开始倒计时,10 秒内必须返回
BroadcastReceiver (后台) 60 秒 Android 8.0 后后台广播限制更严,但阈值仍 60s
Service (前台启动) 20 秒 onStartCommand / onCreate 含耗时操作容易中招
Service (后台启动) 200 秒 其实很长了,但网络重试或数据库大事务还是可能超
ContentProvider 10 秒 查询或插入时主线程卡住的话
Input 事件 (点击/触摸) 5 秒 最容易被用户感知,5 秒没响应就弹框
KeyDispatchTimeout 5 秒 按键事件,和 Input 事件走同一套逻辑
我个人的习惯: 别死记硬背这些数字。你只要记住一个原则——主线程不做任何 I/O、网络、复杂计算、锁等待。阈值只是底线,你应该比底线早几倍完成。

触发流程:一条消息引发的血案

系统内部是怎么一步步判定 ANR 的?我曾经跟过源码,画了张流程图,你看一眼就明白。

ANR 触发流程 · 从消息到弹框 应用主线程收到系统消息 AMS 启动对应组件超时计时器 是否超时? 消息正常处理 结束计时,无事发生 超时!触发 ANR 系统收集堆栈信息 system_server 弹出 ANR 对话框 用户选择「等待」 用户选择「关闭」 🗒️ 关键点: • 不同组件阈值不同 • 计时从消息投递开始,不是从执行开始 • 收集的堆栈包含所有线程,不仅仅主线程

几个容易踩的坑

  • BroadcastReceiver 里做异步操作:很多人觉得我开个线程就不超时了。错!onReceive 返回后系统就认为处理完了,你那个线程跑多久它不管。但如果你在 onReceive 里直接做耗时任务,10 秒超时一定炸。
  • ContentProvider 的 query 在 UI 线程执行:我遇到过 Room 在主线程查数据,结果磁盘 I/O 卡了 8 秒,正好撞上 ContentProvider 超时。其实 allowMainThreadQueries() 是罪魁祸首。
  • Input 事件 5 秒为什么最严格? 因为用户感受最直接——点一下屏幕,手机半天没反应。其他组件的超时用户可能感知不到,但触摸无响应立马就会点「关闭」。
我曾经踩过的雷: 在 Service 的 onStartCommand 里用 Thread.sleep(15000) 模拟网络等待——前台启动 20 秒阈值看似安全,但当多个 Intent 连续到来时,每个 onStartCommand 串行执行,累计时间轻易超过 20 秒。我那次是后台推送批量处理,ANR 日志里 Service 耗时显示 35 秒……教训就是:有任何长时间操作都丢到工作线程,或者用 IntentService / JobIntentService。

小结

ANR 的触发机制说复杂也复杂,说简单也简单——就是系统给你设了个闹钟,到点了你还赖在床上,它就告状。不同组件的阈值从 5 秒到 200 秒不等,但我建议你统一按照 5 秒的标准来写代码:只要是主线程,任何操作超过 5 秒都算高危。

你想想看,Retrofit 网络请求超时我们通常设 10 秒、30 秒,如果放在主线程发起同步请求,那就等于埋了一颗定时炸弹。后面我会专门分析 Retrofit 超时与 ANR 的关联,今天先把阈值和触发流程吃透。