Nexus 5X安装AAB时资源缺失崩溃问题求助
问题现象
- 在Nexus 5X模拟器上单独安装AAB拆分出的
base-master.apk或base-master_2.apk时,触发如下崩溃:
Caused by android.content.res.Resources$NotFoundException: Resource ID #0x7f0800f9
at android.content.res.ResourcesImpl.getValueForDensity(ResourcesImpl.java:224)
at android.content.res.Resources.getValueForDensity(Resources.java:1334)
at android.graphics.drawable.BitmapDrawable.updateStateFromTypedArray(BitmapDrawable.java:798)
at android.graphics.drawable.BitmapDrawable.inflate(BitmapDrawable.java:754)
- 该AAB拆分出的APK包括:
- base-hdpi.apk、base-ldpi.apk、base-master.apk、base-master_2.apk
- base-mdpi.apk、base-tvdpi.apk、base-xhdpi.apk、base-xxhdpi.apk、base-xxxhdpi.apk
- 其他多语言区域APK
- 同时安装Master APK+对应密度APK(比如base-master.apk搭配base-hdpi.apk)时完全正常;只保留
drawable目录下的图片、删除drawable-xxhdpi和drawable-xxxhdpi目录后,单独安装Master APK也能修复崩溃,但需求是保留不同密度目录下的不同尺寸图片,尝试创建全密度drawable目录后问题依旧。
原因分析
AAB的拆分机制会把密度相关的资源单独打包到对应密度的APK里,Master APK只存储没有密度限定的通用资源。当单独安装Master APK时,Nexus 5X是xxhdpi设备,系统会优先查找xxhdpi密度的资源,但该资源仅存在于base-xxhdpi.apk中,Master APK里没有,自然触发资源找不到的崩溃。
只保留drawable目录时,系统会回退使用通用目录的资源,所以不会崩溃;但创建全密度目录无效,是因为拆分机制会自动将带密度限定的目录资源分到对应密度APK,不会留在Master APK里。
解决方案
方案1:指定部分密度资源打包进Master APK
在Module级别的build.gradle里配置bundle选项,把需要的密度资源强制留在Master APK中:
android { bundle { density { // 列出要包含进Master APK的密度类型 include "hdpi", "xxhdpi", "xxxhdpi" // 关闭这些密度的拆分,资源直接打包进Master APK split = false } } }
这样指定的密度资源会和Master APK绑定,单独安装时系统能找到对应密度的图片。
方案2:添加nodpi兜底资源
不想修改拆分规则的话,可以在drawable-nodpi目录下放一份该图片的通用版本(分辨率选mdpi或适配通用尺寸即可)。nodpi目录的资源不会被拆分到密度APK,会一直留在Master APK里,当系统找不到对应密度的资源时,会自动使用这个兜底资源,避免崩溃。
方案3:完全禁用密度拆分(不推荐)
如果不在乎APK体积,可以直接关掉密度拆分,所有密度资源都打包进Master APK:
android { bundle { density { enableSplit = false } } }
这个方法会让Master APK体积变大,仅适合资源体积较小的应用。
内容的提问来源于stack exchange,提问作者android nama

