Android 打包编译开启了shrinkResources true,导致 Resources.getIdentifier() 使用的动态资源被移除的问题

问题

release 版本的包上出现图片无法显示的问题,出现以下错误日志:

android.content.res.Resources$NotFoundException: Drawable ******:drawable/** with resource ID #0x7f08012e

之前在 debug 版一直没有出现,因为用的 SDK 需要把图片资源放到 drawable 下,分析了下 apk 包,发现相应的图片资源没有被打包进来,起初认为是混淆的原因,但是混淆只是针对代码,后发现了这个配置 shrinkResources true

Android 打包设置 shrinkResources true 引发的问题分析

当配置 shrinkResources 的值为 true 时,gradle 在打包编译的时候会将未引用的例如图片等资源文件移除。

shrinkResources 必须和 minifyEnabled 配合使用达到减少包体积的作用,只有删除了无用的代码之后,才能知道哪些资源是无用的,如果想查看那些资源未使用可以使用如下命令:

./gradlew clean assembleDebug --info | grep "Skipped unused resource"

一些 SDK 使用 getResources().getIdentifier() 动态获取图片,开启 shrinkResources true 后,无用资源被删除,导致 getResources().getIdentifier() 调用的地方出现问题。

int drawableId = getResources().getIdentifier("icon", "drawable", getPackageName()) ;

解决方案

保留使用到的图片,使用是并没有在程序中引用,在打包时也开启了 shrinkResources 的值为 true 移除无用资源,和混淆可以配置 keep 类似,资源同样也可以通过tools:keep来指定要保留的资源文件,通常通过 res/raw/keep.xml 指定要保持的资源,如




同样可以通过 tools:discard 来从保持的资源中指定要删除的资源,如

tools:discard="@layout/unused2" 

你可能感兴趣的:(Android 打包编译开启了shrinkResources true,导致 Resources.getIdentifier() 使用的动态资源被移除的问题)