ProGuard多injars转多outjars:如何配置过滤器与一对一映射?
这个问题我之前帮同事排查过,其实就是ProGuard在处理多组输入输出Jar包时,没搞清楚你要给每个输出Jar分配哪些内容,才会抛出这个提示。咱们一步步来解决:
为啥会出现这个报错?
当你配置多个outjars时,如果第一个输出Jar没有指定明确的过滤器,ProGuard会默认把所有injars里的内容全塞到第一个输出Jar里,后面的输出Jar自然就没东西可处理了,于是就弹出这个警告(本质是提醒你别搞出空Jar)。核心逻辑就是:必须让ProGuard清楚每个输出Jar对应哪些输入的类或资源。
怎么配置一对一映射和过滤器?
核心思路是给每一组injars+outjars搭配专属的过滤规则,明确指定哪些内容要进入当前输出Jar,剩下的交给后续的输出Jar处理。
1. 基础一对一映射示例
假设你有两个输入Jar:app-core.jar(核心业务类)和app-ui.jar(界面相关类),要分别输出混淆后的proguarded-core.jar和proguarded-ui.jar,配置可以这么写:
# 第一组:处理核心业务Jar -injars app-core.jar -outjars proguarded-core.jar # 过滤器:只保留com.example.core包下的所有类(根据你的实际包名调整) -keep class com.example.core.** { *; } # 第二组:处理界面相关Jar -injars app-ui.jar -outjars proguarded-ui.jar # 过滤器:只保留com.example.ui包下的所有类 -keep class com.example.ui.** { *; } # 通用混淆配置(按需调整) -dontshrink -dontoptimize -keepattributes SourceFile,LineNumberTable # 其他通用规则(比如保留序列化类、枚举类等)...
2. 更精细的内容过滤
如果你的输入Jar有重叠的包名,或者需要拆分同一个输入Jar里的内容到不同输出Jar,可以用包含/排除过滤器精准控制:
- 用括号
()在-injars后直接指定要包含的内容,比如-injars common.jar(com/example/core/**) - 用
!符号排除不需要的内容,比如-injars common.jar(!com/example/ui/**)
举个例子:你有一个common.jar,里面既有core又有ui的类,要把core部分放到第一个输出Jar,ui部分放到第二个,配置如下:
# 第一组:提取common.jar的core部分 + app-core.jar的全部内容 -injars common.jar(com/example/core/**) -injars app-core.jar -outjars proguarded-core.jar -keep class com.example.core.** { *; } # 第二组:提取common.jar的ui部分 + app-ui.jar的全部内容 -injars common.jar(com/example/ui/**) -injars app-ui.jar -outjars proguarded-ui.jar -keep class com.example.ui.** { *; }
3. 资源文件的过滤
如果需要保留资源文件(比如xml、图片),可以用-keepresources规则,比如要把所有xml资源放到当前输出Jar:
-keepresources **/*.xml
小技巧:验证配置是否正确
配置完可以先运行ProGuard的-printconfiguration参数,输出完整的配置解析结果,检查每个输出Jar的过滤规则是否正确;或者直接查看输出的Jar包内容,确认每个Jar都包含了对应的类和资源。
内容的提问来源于stack exchange,提问作者eastwater

