构建App Bundle时tools:keep为何被忽略?如何解决?
为啥APK和App Bundle的Proguard表现不一样?
APK和App Bundle的资源处理逻辑有本质区别:
- 打包APK时,资源收缩是针对整个包做分析,你写的
keep.xml规则会直接生效,只要匹配到*_thumb的drawable就会被保留。 - 但打包App Bundle时,AGP会把资源按密度、语言拆成独立的资源分片(split),资源收缩的可达性检查更严格。如果你的图片是通过动态方式引用的(比如用字符串拼资源名再加载),默认会被判定为未使用;而且
keep.xml的规则在分片拆分阶段可能没被正确识别,导致Proguard还是标记这些图片不可达。
用keep.xml解决的具体方法
1. 修正keep.xml的位置和规则
首先确保keep.xml放在src/main/res/values/目录下(这是AGP默认读取的位置),然后修改内容:
<resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@drawable/*_thumb" tools:shrinkMode="strict" />
- 加上
tools:shrinkMode="strict"是强制资源收缩工具严格遵守你的keep规则,避免误删匹配的资源。 - 不管你的图片在
drawable-mdpi还是drawable-xhdpi,@drawable/*_thumb都会覆盖所有密度下的同名资源,不用单独写每个目录。
2. 配合Proguard规则加固(可选但推荐)
如果你的代码是通过反射资源ID来加载图片的,还要在proguard-rules.pro里添加这条规则,确保drawable的资源ID不被混淆或移除:
-keepclassmembers class **.R$drawable { public static <fields>; }
这样Proguard和资源收缩工具都会意识到这些资源是被间接引用的,不会随便删掉。
3. 验证结果
打包App Bundle后,你可以:
- 查看Proguard日志,确认
*_thumb开头的图片不再被标记为不可达。 - 从Bundle导出测试APK,查看
resources.txt或者直接解压APK查看drawable目录,确认目标图片已被包含。
内容的提问来源于stack exchange,提问作者Al0x
相关产品推荐
相关产品推荐

