7

I have a project which contains a lot of drawables, which are named starting with "a" or "b" (For example a1_back, a2_back, b1_start, b2_start and many-many more). Those drawables are not used in code, but used by the following code:

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

So, nowhere in code do I have specific string "a1_back" used. That's why when I set "shrinkResources true" all my drawables starting with "a" and "b" are removed.

I've read that you can specify what resources to keep using following xml file:

<?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" />

But I have way to many drawables and don't want to specify each one separately. Is there a way to set a pattern in "tools:keep"(to keep all drawables starting with "a" or "b") or maybe make it keep all drawables in project, but remove other unused resources?

Thanks in advance! :)

hkop
  • 294
  • 2
  • 9
  • if you are dealing with only resources, android studio have an option click on **Refactor** >> **Remove Unused Resources**. – Akshay Bhat 'AB' Dec 22 '16 at 10:43
  • Yes, but I don't want my drawables to be removed! i want to keep them, but remove everything else. – hkop Dec 22 '16 at 10:45
  • Run the remove unused resources, then use your source control program to restore the drawables. – nasch Dec 23 '16 at 22:29

2 Answers2

3

When accessing resource dynamically , use this trick as explained in Android User Guide using this example

String name = String.format("img_%1d", angle + 1);
res = getResources().getIdentifier(name, "drawable", getPackageName());
Mohamed ALOUANE
  • 5,099
  • 5
  • 28
  • 56
2

There is a workaround you can use. Add a prefix for all drawables which you want to keep

@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;
    }
}

The trick here

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

Resource shrinking mechanism analyzes that all drawables with "prefix_" can be used and it doesn't touch these files.