Android构建App Bundle报错uses reserved file or directory name 'res'
问题根因
这个报错的核心诱因是你引入的某个依赖(大概率是本地AAR或小众私有仓库依赖)存在打包结构错误,将res目录直接放在了归档包的根路径下,触发了bundletool的路径合法性校验——AAB格式规定res是模块内的保留目录名,不允许在包根路径直接出现同名文件/文件夹。
你之前添加exclude 'AndroidManifest.xml'属于错误的治标操作:只是把最先触发校验的manifest文件藏起来了,没有处理根路径下非法的res目录,所以才会出现排除一个资源目录后,其他hdpi、layout等路径下的文件挨个触发报错的现象。全局排除资源目录的操作还会导致最终安装包缺失资源,线上触发Resources.NotFoundException崩溃。
排查步骤
- 执行Gradle命令定位依赖:在项目根目录执行
./gradlew app:dependencies --configuration DEVreleaseRuntimeClasspath,输出DEV release构建变体下的所有运行时依赖,优先排查本地引入的AAR、长期未更新的私有SDK、小众开源组件,主流官方开源库不会出现这类低级打包错误。 - 快速定位问题文件:打开
app/build/intermediates/目录下对应DEVrelease变体的合并依赖、合并资源临时目录,逐层查找解压后的依赖包,找到哪个包的根目录直接存在res文件夹(标准AAR结构的res应该在对应包名的层级目录下,不会直接出现在归档根目录),即可锁定问题依赖。
修复方案
- 立刻删除
packagingOptions里的exclude 'AndroidManifest.xml'配置,该配置会直接破坏AAB的合法结构,就算后续打包通过也会出现安装失败、组件找不到的问题。 - 如果是本地AAR导致的问题:将问题AAR解压,把根目录下错位的
res目录移动到对应包名的正确路径下,删除根目录多余的res文件夹后重新打包AAR,替换项目中原有的错误AAR即可。 - 如果是远程依赖导致的问题:优先升级该依赖到已经修复打包结构的版本;如果没有可升级版本,添加精准排除规则过滤非法的根路径res目录,参考配置如下:
packagingOptions { doNotStrip "*/armeabi/*.so" doNotStrip "*/armeabi-v7a/*.so" doNotStrip "*/arm64-v8a/*.so" doNotStrip "*/x86/*.so" doNotStrip "*/x86_64/*.so" doNotStrip "*/mips/*.so" doNotStrip "*/mips64/*.so" // 仅排除包根目录下非法的res目录,不会影响正常模块合并到各feature/base下的合法资源 exclude 'res/**' }
注意:不要添加类似
exclude '**/drawable-anydpi-v24/*.xml'这类针对具体资源目录的全局排除规则,会误删正常资源。
内容的提问来源于stack exchange,提问作者Manish
相关产品推荐
相关产品推荐

