第4章 LeakCanary 集成与配置:依赖引入、版本选择、白名单设置、日志输出解读
4.1 现象识别——LeakCanary 不工作或误报
当 LeakCanary 未正确集成时,开发者通常遇到以下三类现象:
- 静默失效:发生内存泄漏后,通知栏无泄漏图标、Logcat 无 LeakCanary 输出、Heap dump 未生成。
- 启动崩溃:Application 初始化阶段抛出
ClassNotFoundException或NoClassDefFoundError。 - 误报 / 白名单遗漏:每次 Activity 销毁都报告泄漏,但实际是系统缓存或框架对象,导致无效告警淹没有效泄漏。
| 现象 | 直接原因 | 排查优先级 |
|---|---|---|
| 静默失效 | 依赖版本不兼容 / 未正确初始化 / ProGuard 混淆规则缺失 | 高 |
| 启动崩溃 | 依赖坐标错误 / 编译 compileOnly 误用 / 构建变体不匹配 |
高 |
| 误报 | 白名单未配置 / 白名单类名与实际 GC root 不匹配 | 中 |
⚠️ 关键规则: 不要在生产包中启用 LeakCanary 自动 dump。务必使用
debugImplementation 或构建变体限定。参考官方 leakcanary-android-release 的 no-op 模块。
4.2 数据采集——获取配置信息与日志
- 确认依赖生效:查看
.gradle缓存或依赖树./gradlew :app:dependencies --configuration debugImplementation - 抓取 LeakCanary 自身日志:过滤 Logcat tag
LeakCanary、LeakCanary-Info、LeakCanary-Debug。典型有效日志:D/LeakCanary: LeakCanary is running, ready to detect leaks. D/LeakCanary: Watching activity com.example.MainActivity (fragment accepted) D/LeakCanary: Scheduling check for retained instances in 5 seconds D/LeakCanary: Analysis in progress, working on retained instances... D/LeakCanary: Heap dump file path: /data/data/com.example/cache/leakcanary/xxx.hprof - 获取 Heap dump 文件:通过 Device File Explorer 提取
/data/data/{package}/cache/leakcanary/目录下的.hprof。 - 白名单配置检查:在 Logcat 过滤
IgnoredClassReachability可看到哪些类被跳过。例如:LeakCanary: IgnoredClassReachability: android.arch.lifecycle.ReportFragment injected by framework - ignoring.
📋 采集清单: 依赖版本号 & 构建变体 → Logcat 全量 LeakCanary 日志 → dump 文件列表 → 白名单生效日志。
4.3 原因定位——故障树分析法
4.4 修复动作——依赖引入、版本选择、白名单配置
4.4.1 依赖坐标与版本选择规则
| LeakCanary 版本 | Gradle 坐标(debugImplementation) | 适用 Gradle / AGP | 关键变化 |
|---|---|---|---|
| 2.7 及之后 | com.squareup.leakcanary:leakcanary-android:2.13 |
AGP 7.0+ / Gradle 7.0+ | 支持自动配置;无需手动 install |
| 2.4 – 2.6 | com.squareup.leakcanary:leakcanary-android:2.6 |
AGP 4.2+ / Gradle 6.8+ | 需在 Application 中调用 LeakCanary.install(application) |
| 1.6.x | com.squareup.leakcanary:leakcanary-android:1.6.3 |
AGP 3.x | 已停止维护;不推荐新项目使用 |
✅ 版本选择黄金规则:
- 新项目直接使用 2.13(2024年最新稳定版)。
- 若项目使用 Java 8 且 AGP ≥ 7.0,首选 2.7+ 系列。
- 避免使用
SNAPSHOT或alpha版本用于生产调试。
4.4.2 build.gradle 正确配置示例
// app/build.gradle
android {
// ...
buildTypes {
release {
// 确保 release 构建下没有 LeakCanary 的自动 dump
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
// 仅在 debug 变体引入
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.13'
// release 变体使用 no-op 空模块
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:2.13'
// 可选:测试变体也启用
testImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:2.13'
}
4.4.3 白名单设置方法
白名单用于跳过已知不构成泄漏的系统对象或框架缓存。在 assets/leakcanary-ignored-classes.txt 中配置,一行一个类全限定名:
# Android framework 常见误报
android.arch.lifecycle.ReportFragment
android.app.ActivityManager
com.android.internal.policy.DecorView
android.view.inputmethod.InputMethodManager
# 第三方 SDK 缓存
com.example.sdk.CommonCache
com.bumptech.glide.manager.SupportRequestManagerFragment
# 自定义接口回调(确认生命周期正确时)
com.example.app.GlobalCallback
⚠️ 白名单陷阱排查规则:
- 类名必须与 Heap dump 中的 GC Root 类型完全一致(包含包名)。
- 忽略行首空格,但类名后不能有尾随空格。
- 可以使用
#注释,但注释不能写在同一行类名后。 - 若白名单不生效,检查文件路径是否准确:应为
src/main/assets/leakcanary-ignored-classes.txt,而非assets子目录。
4.4.4 ProGuard / R8 保留规则
若使用混淆,必须保留 LeakCanary 内部类和泄漏分析器:
-keep class leakcanary.** { *; }
-keep class shark.** { *; }
# 如果你手动 install,保留 Application 子类中的 install 调用
-keepclasseswithmembers class * extends android.app.Application {
public void onCreate();
}
4.5 复测——验证集成生效
- 验证依赖生效:在 Application 启动时加一行日志
Log.d("LeakCheck", "LeakCanary installed: " + LeakCanary.isInAnalyzerProcess);(仅在 debug 下)。 - 制造人工泄漏:在 Activity 中持有静态 Context 引用,然后快速旋转屏幕,观察 5 秒后是否出现通知。
- 检查白名单日志:过滤
IgnoredClass,确认系统类被正确跳过。 - 验证 release 包无影响:切换 build variant 到 release,确认 apk 中不包含
leakcanary相关类(可通过反编译或检查 dex 字节数)。
4.6 预防——集成规范 checklist
| 检查项 | 要求 | 验收方式 |
|---|---|---|
| 依赖限定 | debugImplementation 与 releaseImplementation no-op 配对 |
依赖树输出 |
| 版本锁定 | 使用全平台统一版本号,不应存在多个 LeakCanary 版本 | gradle dependencies | grep leakcanary |
| 白名单文件 | 文件位于 src/main/assets/leakcanary-ignored-classes.txt |
手动检查路径 |
| ProGuard 保留 | 包含 leakcanary 和 shark 包 |
反编译 release apk |
| 初始化检查 | LeakCanary 2.7+ 自动注册,无需手动调用 | Logcat 确认 |
| 误报监控 | 每周 review 泄漏报告,确认白名单是否需要更新 | 持续集成任务 |
🔧 最佳实践: 在 CI 的 debug 构建中启用 LeakCanary,并编写单元测试验证指定 Activity 在销毁后无 retain 实例。参考
com.squareup.leakcanary:leakcanary-android-instrumentation 模块。