Files
mkdocs/docs/学习笔记/Android ANR 知识点总结.md
renjianbo e242160702 更新: MkDocs知识库同步
- 女童生长激素项目文档更新
- 新增Android ANR知识点总结
- 任务执行: DevOps工程师
- 指令来源: CEO张伟明 → 任总
- 时间: 2026-03-31 00:15
2026-03-31 00:16:21 +08:00

4.6 KiB
Raw Permalink Blame History

1. 什么是 ANR

ANR 全称:Application Not Responding,即应用程序无响应。

2. 触发条件

  1. 只有 ** 主线程(UI 线程)** 才会产生 ANR。

  2. 必须发生输入事件或特定组件操作:

    • 按键、触屏等输入事件
    • BroadcastReceiver 生命周期回调
    • Service 生命周期回调
  3. 事件响应超时,不同场景超时时间不同。

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 线程不一定耗 CPU
  • TIMED_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 日志分析

  1. 搜索 ANR in:定位发生 ANR 的进程
  2. 搜索 ActivityManager:CPU usage from:判断是否 CPU 过高

5.2 traces.txt 分析

  1. 搜索 held by tid=:排查死锁
  2. 查看 stackSize=:判断是否内存问题

5.3 整体分析步骤

  1. 确定 ANR 时间点

    • 关键字:anr in、blocked、blockMonitor、freezedector
    • 获取:版本号、PID、是否前台、页面、温度、频点、ANR 类型
  2. 根据 ANR 类型回溯对应时间段日志

    • 查找 Subject / Reason
  3. 分析 ANR 堆栈

    • 查找 sysTid=线程号
    • 状态为 block/timeout 一般为真实问题堆栈

5.4 核心分析思路

  1. 查看 CPU 负载

    • user:用户态
    • kernel:内核态
    • iowait:IO 等待
    • faults:内存缺页
  2. 查看主线程状态

    • Native:正常空闲,等待消息
    • Runnable:主线程执行耗时操作
    • Blocked:主线程被锁阻塞,可查 waiting to lock...held by thread
  3. 其他应用抢占 CPU

    日志会显示高占比包名,CPU 上限 = 核心数 × 100%

  4. 系统服务 / Binder 问题

    搜索:BinderProxy.transactNative

    可能原因:Binder 超时、Binder 资源耗尽

  5. 内存紧张导致 ANR

    • 查看 ANR 前空闲内存

      • 4G 及以下:阈值约 350M
      • 4G 以上:阈值约 450M
    • 查看 trimMemory 调用(level 越大内存越紧张:5/10/20/40/60/80)

6. 典型示例

  1. 主线程与子线程互锁导致 ANR
  2. Android 系统库崩溃(如 libweexcore.so 等)
  3. nativePollOnce 阻塞
  4. Binder 对端阻塞(如第三方推送 SDK)

7. 非应用自身导致的 ANR

  1. 热限频

    • 温度 > 41℃
    • 大核频点 < 1.8GHz 且跑满
  2. Monkey 异常场景

    • 焦点不在当前应用 / 页面已销毁,仍分发输入事件
    • 不属于 App 代码问题

8. ANR 根本原因分类总结

表格

原因类别 具体表现
主线程自身问题 主线程执行耗时操作、死循环、复杂计算、同步 IO / 网络
线程间竞争 主线程等待子线程锁、死锁、子线程崩溃导致主线程无限等待
CPU 被抢占 其他进程占满 CPU、频繁 GC
系统资源瓶颈 内存紧张、GC 频繁、系统服务繁忙、Binder 耗尽
系统 / 环境问题 热限频、Monkey 异常、系统服务超时