Android: 使 "shrinkResources true" 保留所有可绘制对象,但删除其他未使用的资源

Android: Make "shrinkResources true" to keep all drawables, but remove other unused resources

我有一个包含很多可绘制对象的项目,这些可绘制对象的名称以 "a" 或 "b" 开头(例如 a1_back、a2_back、b1_start、b2_start 等等)。这些可绘制对象未在代码中使用,但被以下代码使用:

String name = image.getName();//getName() returns for examle "a1_back"
res = getResources().getIdentifier(name, "drawable", getPackageName());

所以,我在代码中的任何地方都没有使用特定的字符串 "a1_back"。这就是为什么当我设置“shrinkResources true”时,所有以 "a" 和 "b" 开头的可绘制对象都被删除的原因。

我读到您可以指定继续使用以下 xml 文件的资源:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/l_used_c"
    tools:discard="@layout/unused2" />

但是我有很多可绘制对象,不想单独指定每一个。有没有办法在 "tools:keep" 中设置模式(以保留所有以 "a" 或 "b" 开头的可绘制对象)或者让它保留项目中的所有可绘制对象,但删除其他未使用的资源?

提前致谢! :)

您可以使用一种解决方法。为所有要保留的可绘制对象添加前缀

@Nullable
private Drawable getDrawableByName(@NonNull final Context context, @NonNull final String name) {
    final String prefixName = String.format("prefix_%s", name);
    return getDrawable(context, prefixName);
}

@Nullable
protected Drawable getDrawable(@NonNull final Context context, @NonNull final String name) {
    final Resources resources = context.getResources();
    final int resourceId = resources.getIdentifier(name, "drawable", context.getPackageName());
    try {
        return resources.getDrawable(resourceId, context.getTheme());
    } catch (final Resources.NotFoundException exception) {
        return null;
    }
}

技巧在这里

final String prefixName = String.format("prefix_%s", name);

资源压缩机制分析,所有"prefix_"的drawable都可以使用,不涉及这些文件。

动态访问资源时,使用此技巧,如 Android User Guide 使用此示例

中所述
String name = String.format("img_%1d", angle + 1);
res = getResources().getIdentifier(name, "drawable", getPackageName());