Proguard(R8)取反运算符失效:无法保留除Apache包外的类
我之前也踩过类似ProGuard规则写法和优先级的坑,来帮你一步步梳理问题并给出解决方案:
为什么你的第一个规则-keep class !org.apache.**没生效?
这个写法的核心问题是缺少对类成员的明确声明,而且ProGuard的规则需要清晰定义保留范围。单独写-keep class !org.apache.**只相当于告诉ProGuard“不保留org.apache包下的类”,但没有明确指定要保留其他类的哪些成员——默认情况下,ProGuard会混淆所有未被明确标记保留的类和成员,所以才会出现所有类都被混淆的结果。
另外你提到用-printconfiguration看到自定义规则后有大量自动生成的-keep规则,这是Android Studio自动添加的(比如依赖库自带的consumer规则、Android默认的组件保留规则),这些规则的执行顺序在你的自定义规则之后,会直接覆盖你之前的排除逻辑。
为什么Ezekiel的方案反而保留了所有类?
那个方案里的-dontshrink -dontoptimize -dontobfuscate三个参数直接关闭了ProGuard的压缩、优化、混淆三大核心功能,相当于完全禁用了代码混淆流程,自然所有类都会被完整保留,这和你“混淆Apache类、保留其他类”的需求完全相悖,所以这个方案并不适用。
正确的解决方案
要实现“保留除Apache库外的所有类(允许混淆Apache包下的类,其他类完整保留)”,可以按以下步骤配置:
修正核心规则:明确保留非Apache类的成员,同时允许处理Apache类
在proguard-rules.pro中添加:# 保留所有非org.apache包下的类及其公共/受保护成员 -keep class !org.apache.** { public protected *; } # 避免Apache库因未引用代码触发编译警告 -dontwarn org.apache.**确保规则执行顺序:
Android Studio默认先加载自定义规则,再加载自动生成的规则。为了让你的排除规则生效,可以在build.gradle中明确指定规则文件顺序,确保自定义规则最后执行:android { buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' # 若有其他规则文件,确保proguard-rules.pro排在最后 } } }验证规则效果:
重新打包后,添加-printmapping mapping.txt生成混淆映射文件,检查Apache包下的类是否被重命名,而非Apache类是否保持原名;也可以用Android Studio的APK Analyzer查看APK内的类名,确认最终效果。
额外注意事项
- 如果项目中还有其他需要排除的第三方库,可以在取反规则后添加更多项,用逗号分隔:
-keep class !org.apache.**,!com.example.thirdparty.** { public protected *; } - 不要随意添加
-dontshrink这类禁用参数,除非你明确需要关闭对应功能。
内容的提问来源于stack exchange,提问作者OneWorld

