Skip to content

Latest commit

 

History

History
86 lines (62 loc) · 3.6 KB

CLAUDE.md

File metadata and controls

86 lines (62 loc) · 3.6 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project overview

anr-message-monitor — Android 主线程消息监控 SDK,实时监控主线程消息调度,检测 ANR 根因。包含一个 Android Library 模块 (sdk/) 和一套 Python 可视化分析工具 (scripts/)。

Build commands

# 编译 SDK AAR
./gradlew :sdk:assembleRelease

# 收集完整 SDK 发布包(AAR + sources.jar + proguard)
./gradlew :sdk:assembleSdk

# 打包发布 zip
./gradlew :sdk:packageSdk

# 安装 Python 依赖
pip install -r requirements.txt

输出 AAR 位置:sdk/build/outputs/aar/,完整发布包:sdk/build/outputs/sdk/

Python analysis tool

# 从设备拉取 dump 数据后分析
python scripts/analyze.py <dump_file.jsonl> [output_dir]

# 生成测试数据
python scripts/generate_test_data.py

Architecture

SDK 数据流

LooperHook (Printer 注入)
  ├─→ 每条消息: Wall/Cpu 计时 + 分类 + 堆栈采样
  └─→ DataAggregator (4 种聚合策略)
        └─→ RingBuffer<DispatchRecord> (内存循环缓冲区)
              └─→ triggerDump → RecordWriter → JSONL 文件

QueueSniffer (每 100ms 反射遍历 MessageQueue)
  └─→ snapshotHistory + barrier 检测 → 自动 triggerDump

核心组件

组件 职责
MessageMonitor SDK 单例入口,协调各组件生命周期,配置管理
LooperHook 通过 Looper.setMessageLogging(Printer) 注入,解析 ">>>>> Dispatching" / "<<<<< Finished" 日志行获取每条消息的 Wall/CPU 耗时
QueueSniffer 反射遍历 MessageQueue.mMessages 链表,检测 Barrier(msg.target == null)和消息积压。必须在主线程调用
StackSampler 消息执行 >500ms 时在子线程定时抓取主线程堆栈,停止多帧堆栈对齐
DataAggregator 聚合阈值 300ms:连续短消息累加合并(AGGREGATED),单条超阈值拆分(SINGLE),系统组件消息单独标记(KEY_MSG),空闲间隙识别(IDLE)
MessageClassifier 基于 ActivityThread.H 的 what 值(100-159)和 Handler 类名将消息分类为 ACTIVITY/SERVICE/BROADCAST/VSYNC/INPUT/IDLE/BARRIER/APP_START/PROVIDER/CUSTOM
RingBuffer 线程安全的固定容量循环缓冲区(默认 200),满时覆盖最旧记录
RecordWriter 子线程写入 JSONL(每行一条 JSON),含 meta/record/snapshot 三种类型
CpuTimeReader 读 /proc/self/task/{tid}/stat 的 utime+stime 字段,jiffies→ms。回退到 Process.getElapsedCpuTime()

自动 dump 触发条件

  • Barrier 检测到 → 立即 dump(5s 限频)
  • 待调度消息 > 50 条 → 自动 dump
  • Watchdog 5s 无响应 → 标记疑似 ANR → dump
  • MessageMonitor.stop() → dump 残余数据
  • 手动调用 MessageMonitor.dump(reason)

Python 分析管线

analyze.py 作为主入口调用各图表模块,数据模型(parser.py 中的 dataclass)与 Android 端 Kotlin data class 结构一一对应。compute_relative_timestamps() 将所有时间戳转为相对秒数后传递给各 chart 模块。每个 chart 模块独立绘制一张 PNG 图。

关键常量

  • 聚合阈值: 300ms(DataAggregator.AGGR_THRESHOLD_MS)
  • 默认环形缓冲区容量: 200(MessageMonitor.ringBufferCapacity)
  • 默认队列检测间隔: 100ms
  • 堆栈采样间隔: 500ms(与系统 ANR 超时检测对齐)
  • 最大快照历史: 300 条
  • 最大待调度消息扫描: 20 条详情 + 继续计数
  • minSdk: 21, compileSdk: 35, JVM target: 11, Kotlin 2.1.0, AGP 8.7.3