第1章 ANR现象识别:事件超时、无响应对话框、trace日志特征、关键字段
ANR(Application Not Responding)是Android系统对应用主线程长时间阻塞的最终裁定。本章从识别阶段出发,建立三层观察视角:用户感知层、系统日志层、Trace文件层。只有准确识别ANR现象的各个表象,才能避免误判、漏判,为后续数据采集与定位打下基础。
1.1 现象分层识别表
| 识别维度 | 表现形式 | 判断依据 | 是否必现 |
|---|---|---|---|
| 用户感知层 | 屏幕触摸无响应、点击无效、动画卡住 | 操作后3秒内无视觉反馈 | 通常可复现 |
| 系统对话框层 | 弹出"应用无响应"对话框,含"等待"与"关闭"选项 | 前台应用主线程超时5秒 | 必现(超时发生后) |
| Trace日志层 | /data/anr/traces.txt 生成,logcat输出"ANR in"关键字 | 系统dump所有线程堆栈 | 每次ANR必然落盘 |
| 关键监控字段 | "waiting on"、"blocked on"、"held by"、"suspend all" | 主线程处于BLOCKED/WAITING状态 | Trace中固定格式 |
1.2 三类ANR判断规则
- 输入事件超时:触摸/按键事件5秒内未分发完成 → 触发ANR
- 广播超时:前台BroadcastReceiver 10秒 / 后台60秒未执行完
- 服务超时:Service 20秒内未完成onCreate/onStartCommand
实战要点:权限回调引发的ANR通常属于"输入事件超时"类别,但Trace中主线程堆栈会停留在权限请求的回调方法上,而不是事件分发入口。
1.3 关键Trace日志特征
// 典型的权限回调ANR Trace日志片段
"main" prio=5 tid=1 Blocked
| group="main" sCount=1 dsCount=0 flags=1 obj=0x74c0a478 self=0x7fc0a0a000
| sysTid=12345 nice=-10 cgrp=default sched=0/0 handle=0x7fc0a0f000
| state=S schedstat=( 123456789 98765432 123 ) utm=12 stm=8 core=4 HZ=100
| stack:
at com.example.app.PermissionCallback.onRequestPermissionsResult(PermissionCallback.java:45)
- waiting on <0x0b4c2a10> (a java.lang.Object)
at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:8123)
at android.app.ActivityThread.dispatchActivityResult(ActivityThread.java:5432)
at android.app.ActivityThread$ActivityResultCallback.handleResult(ActivityThread.java:6210)
at android.app.ActivityThread.-$$Lambda$6xWq8lJvFd7T0kXzYpRzN9w0oM8.accept(ActivityThread.java:203)
at com.android.server.am.ActivityManagerService$PermissionCallback.onPermissionResult(ActivityManagerService.java:13579)
- locked <0x0b4c2a10> (a java.lang.Object)
常见误判:仅看到"ANR in"关键字就收工,未深入分析主线程堆栈中的"waiting on"和"locked"组合。权限回调的ANR中,主线程可能正处于等待用户授权弹窗响应的同步锁中。
1.4 现象识别故障树
1.5 排查判断速查表
| 观察步骤 | 检查对象 | 满足条件即为ANR | 权限回调场景特征 |
|---|---|---|---|
| 1 | Logcat搜索"ANR in" | 输出包含应用包名 | 权限弹窗前后出现 |
| 2 | 查看/data/anr/traces.txt | 文件存在且时间匹配 | 主线程堆栈含PermissionCallback |
| 3 | 主线程状态 | tid=1 且 state=Blocked/WAITING | stack顶部为onRequestPermissionsResult |
| 4 | 锁关系分析 | "waiting on" + "held by" 同对象 | 权限回调内部存在同步锁竞争 |