- 女童生长激素项目文档更新 - 新增Android ANR知识点总结 - 任务执行: DevOps工程师 - 指令来源: CEO张伟明 → 任总 - 时间: 2026-03-31 00:15
4.6 KiB
4.6 KiB
1. 什么是 ANR
ANR 全称:Application Not Responding,即应用程序无响应。
2. 触发条件
-
只有 ** 主线程(UI 线程)** 才会产生 ANR。
-
必须发生输入事件或特定组件操作:
- 按键、触屏等输入事件
BroadcastReceiver生命周期回调Service生命周期回调
-
事件响应超时,不同场景超时时间不同。
2.1 各场景超时时间
- Activity 输入事件 / 生命周期:主线程 5s 内未处理完毕
- BroadcastReceiver#onReceive():主线程 10s 内未处理完毕
- Service 生命周期:主线程 20s 内未处理完毕
3. ANR 根本原因
3.1 主线程执行耗时操作
典型场景:
- 耗时网络访问
- 大量数据读写、数据库操作
- 硬件操作(如 Camera)
- 多线程被 Binder 对端 block
- 主线程调用
Thread.join()/sleep()/wait()、等待线程锁 - Service Binder 数量达上限,无法与 System Server 通信
- System Server 中 WatchDog 导致 ANR、Service 繁忙超时
3.2 非主线程导致
非主线程持有锁,导致主线程等待锁超时 / 无限等待,最终触发 ANR。
3.3 其他进程 / 系统资源问题
- 其他进程占用 CPU,本进程得不到时间片
- 内存泄漏导致频繁 Full GC,CPU 占用飙升
- 内存吃紧、系统频繁 coredump
CPU 利用率说明:
- 前台进程 ≤ 95%,后台进程 ≤ 5%(无前台时可超)
RUNNABLE线程不一定耗 CPUTIMED_WAITING/WAITING线程不耗 CPU- I/O 操作本身不怎么耗 CPU
注意:
“内存泄露” 可能是真实泄漏点,也可能是堆内存占用过大、内存吃紧,间接导致 ANR/CPU 过高。
4. ANR 类型及日志关键字
表格
| ANR 类型 | 超时时间 | Logcat 关键字 |
|---|---|---|
| InputDispatching Timeout | 5s | Input event dispatching timed out |
| BroadcastTimeout | 前台 10s 后台 60s |
Timeout of broadcast BroadcastRecord |
| ServiceTimeout | 前台 20s 后台 200s |
Timeout executing service |
| ContentProviderTimeout | 10s | timeout publishing content providers |
5. ANR 定位方法
入手点:ANR 前后日志 + /data/anr/traces.txt
5.1 日志分析
- 搜索
ANR in:定位发生 ANR 的进程 - 搜索
ActivityManager:CPU usage from:判断是否 CPU 过高
5.2 traces.txt 分析
- 搜索
held by tid=:排查死锁 - 查看
stackSize=:判断是否内存问题
5.3 整体分析步骤
-
确定 ANR 时间点
- 关键字:
anr in、blocked、blockMonitor、freezedector - 获取:版本号、PID、是否前台、页面、温度、频点、ANR 类型
- 关键字:
-
根据 ANR 类型回溯对应时间段日志
- 查找
Subject/Reason
- 查找
-
分析 ANR 堆栈
- 查找
sysTid=线程号 - 状态为
block/timeout一般为真实问题堆栈
- 查找
5.4 核心分析思路
-
查看 CPU 负载
- user:用户态
- kernel:内核态
- iowait:IO 等待
- faults:内存缺页
-
查看主线程状态
Native:正常空闲,等待消息Runnable:主线程执行耗时操作Blocked:主线程被锁阻塞,可查waiting to lock...held by thread
-
其他应用抢占 CPU
日志会显示高占比包名,CPU 上限 = 核心数 × 100%
-
系统服务 / Binder 问题
搜索:
BinderProxy.transactNative可能原因:Binder 超时、Binder 资源耗尽
-
内存紧张导致 ANR
-
查看 ANR 前空闲内存
- 4G 及以下:阈值约 350M
- 4G 以上:阈值约 450M
-
查看
trimMemory调用(level 越大内存越紧张:5/10/20/40/60/80)
-
6. 典型示例
- 主线程与子线程互锁导致 ANR
- Android 系统库崩溃(如
libweexcore.so等) nativePollOnce阻塞- Binder 对端阻塞(如第三方推送 SDK)
7. 非应用自身导致的 ANR
-
热限频
- 温度 > 41℃
- 大核频点 < 1.8GHz 且跑满
-
Monkey 异常场景
- 焦点不在当前应用 / 页面已销毁,仍分发输入事件
- 不属于 App 代码问题
8. ANR 根本原因分类总结
表格
| 原因类别 | 具体表现 |
|---|---|
| 主线程自身问题 | 主线程执行耗时操作、死循环、复杂计算、同步 IO / 网络 |
| 线程间竞争 | 主线程等待子线程锁、死锁、子线程崩溃导致主线程无限等待 |
| CPU 被抢占 | 其他进程占满 CPU、频繁 GC |
| 系统资源瓶颈 | 内存紧张、GC 频繁、系统服务繁忙、Binder 耗尽 |
| 系统 / 环境问题 | 热限频、Monkey 异常、系统服务超时 |