問題
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
指定要保持的資源,如
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@mipmap/ic_like_icon,@mipmap/ic_share_icon,@layout/l_used_a">
</resources>
同樣可以通過 tools:discard
來從保持的資源中指定要刪除的資源,如
tools:discard="@layout/unused2"