开启 minifyEnabled true 并不等于混淆生效,真正起作用的是规则文件是否覆盖所有必须保留的入口和反射路径;release 构建类型中需配置 minifyEnabled true、shrinkResources true 及 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro',且子模块须用 consumerProguardFiles 注入规则。

直接开 minifyEnabled true 不等于混淆生效,真正起作用的是规则文件是否覆盖了所有必须保留的入口和反射路径。
release 构建类型里必须设置 minifyEnabled 和 proguardFiles
AGP 3.4.0+ 默认用 R8,它完全兼容 ProGuard 规则语法,但构建阶段自动集成,不需要额外插件。关键配置只在 app/build.gradle 的 release 块里:
-
minifyEnabled true:必须打开,否则 R8 完全不运行 -
shrinkResources true:建议同步开启,删掉未引用资源(比如没被代码调用的@drawable/xxx) -
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro':第一个是 AGP 提供的增强默认规则(含优化),第二个是你自定义的规则文件,放在app/目录下
注意:getDefaultProguardFile('proguard-android.txt') 已过时,proguard-android-optimize.txt 才是当前推荐的基线规则。
proguard-rules.pro 里要优先写哪些 -keep 规则
规则不是越多越好,而是要精准覆盖“会被反射、序列化、系统回调或第三方 SDK 强依赖”的类与成员。常见漏写点:
- 四大组件必须显式保留:
-keep public class * extends android.app.Activity、-keep public class * extends android.app.Service等 - 自定义
Application子类不能只写包名通配,得带{*;}否则构造方法可能被删:-keep class com.example.MyApp { *; } - 使用 Gson/Fastjson 的实体类,字段名会因反射失效而为空,得加
-keepclassmembers class * { <fields>; }</fields>或按类单独 keep - 第三方库如 Glide、Retrofit、ButterKnife 都有官方推荐规则,直接抄它们 GitHub 的
proguard-rules.pro片段,别自己猜
错误示例:-keep class com.example.model.** 只保留类名,不保留字段和方法,JSON 解析照样崩。
验证混淆是否真起效,不能只看类名变 a/b/c
类名缩写只是表象,真正要检查的是运行时行为和崩溃堆栈:
- 反编译 release APK(用 jadx-gui),确认关键业务类名、方法名已重命名,且字符串字面量(如 API 路径、埋点事件名)没有明文裸露
- 启动 App,重点测:推送接收、分享回调、DeepLink、WebView JSBridge、Fragment 恢复等依赖反射的路径
- 线上崩溃日志如果出现
NoClassDefFoundError或ClassNotFoundException,大概率是某个类被 shrink 掉了,得加-keep或-keepclassmembers - 查看构建输出目录下的
app/build/outputs/mapping/release/mapping.txt,搜索关键类名,确认它是否出现在映射表中
mapping.txt 里没出现,说明该类已被 R8 删除;出现了但没被重命名,说明 -keep 规则生效了——但这不等于安全,只是没崩。
子模块(library module)的混淆规则怎么生效
子模块自身 build.gradle 里的 minifyEnabled 是无效的,R8 只认主模块(app)的开关。子模块规则必须通过 consumerProguardFiles 注入:
- 在子模块的
build.gradle里写:consumerProguardFiles 'proguard-rules.pro' - 这个文件需放在子模块根目录下,内容只写该模块专用的规则(比如它暴露的 API 类、回调接口)
- 主模块构建时会自动合并所有
consumerProguardFiles和自己的proguardFiles,顺序是:默认规则 → 子模块规则 → 主模块规则
容易踩坑:把子模块规则错写成 proguardFiles,结果构建时不加载,上线后子模块里反射调用失败。


















