如何为Android AAR库正确配置ProGuard生成混淆包?
我明白你现在的困境——给Android库配置ProGuard确实容易踩坑,既要保留对外暴露的API让应用能正常调用,又要混淆内部实现来保护代码。咱们一步步来解决这个问题:
正确配置Android库ProGuard的分步指南
1. 先理清「要保留的公共API」和「可混淆的内部代码」
你之前的问题根源在于:要么没保留足够的公共API导致类被移除,要么过度保留导致完全没混淆。首先得明确:
- 对外暴露的接口、类、公共方法/字段必须保留,不能被ProGuard移除或混淆;
- 内部工具类、私有方法/字段可以放心混淆、压缩。
针对你的场景,调整proguard-rules.pro的保留规则:
# 保留对外暴露的所有公共接口(包括其公共/受保护的成员) -keep public interface com.example.client.** { public protected *; } # 如果你的库有对外提供实例的实现类(比如服务类、工具类),也要保留它们的构造和公共成员 -keep public class com.example.client.** { # 保留构造方法,允许外部实例化 public protected <init>(...); # 保留公共/受保护的方法和字段 public protected *; }
2. 让ProGuard只混淆内部代码,保留公共API名称
你之前的规则会让ProGuard完全不混淆被-keep的类,这显然不是你想要的。可以用-keepnames替代部分-keep,它只会保留名称,允许ProGuard优化未被使用的内部成员,同时混淆非公共的部分:
# 只保留公共类/接口的名称(不混淆),但允许优化内部未使用的成员 -keepnames public class com.example.client.** -keepnames public interface com.example.client.** # 允许混淆内部私有成员(私有方法、字段、内部类) -keepclassmembers class com.example.client.** { private *; private <init>(...); private <methods>; }
3. 添加Android库通用的ProGuard规则
为了避免Android相关的组件(比如注解、枚举、Parcelable)被误处理,补充这些通用规则:
# 保留所有注解,避免依赖注解的逻辑失效 -keepattributes *Annotation* # 保留枚举类的values()和valueOf()方法,这是枚举的标准入口 -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } # 保留Parcelable实现类的CREATOR字段,确保序列化/反序列化正常 -keepclassmembers class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator CREATOR; } # 保留Activity中绑定View的方法(比如onClick) -keepclassmembers class * extends android.app.Activity { public void *(android.view.View); }
4. 验证配置是否生效
配置完成后,做这两步验证:
- 生成release版AAR,查看
build/outputs/mapping/release/mapping.txt文件:确认公共类/接口的名称没被修改,而内部类、私有方法的名称已经变成了a、b这类混淆后的名称; - 在测试应用中集成这个AAR,调用库的所有公共API,确保没有
ClassNotFoundException或NoSuchMethodError这类异常。
内容的提问来源于stack exchange,提问作者Happy




