I'm trying to use an ImageButton
to display a resource, a .png
as a clickable button. When I run my app in debug, the ImageButton
sources the image correctly.
However, when I run the app in release mode the ImageButton
doesn't display the drawable:
I create and populate my ImageButton
s programmatically with:
private void setupButtons() {
FlexboxLayout layout = view.findViewById(R.id.telcosLayout);
final Activity activity = getActivity();
// Telcom is an enum
for (final Telcom t : Telcom.values()) {
ImageButton b = new ImageButton(activity);
int id = getId(t.toString().toLowerCase().replace(" ", "_") + "_logo", R.drawable.class);
Log.i(TAG, "id is " + id);
b.setImageResource(id);
layout.addView(b);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
scanButtonListener.onShowScanButton(t);
}
});
}
}
And the output of my logs when run in release mode is:
2019-10-13 11:07:49.500 25757-25757/? I/select telcome: id is 2131165284
2019-10-13 11:07:49.501 25757-25757/? I/select telcome: id is 2131165320
And here are the logs from running the app in debug mode:
2019-10-13 11:12:22.575 26146-26146/com.glan.input I/select telcome: id is 2131165284
2019-10-13 11:12:22.583 26146-26146/com.glan.input I/select telcome: id is 2131165320
It seems the same drawables are being found in both modes but for some reason they won't display in release mode. What is going on?
I've verified that the drawable exists for all the screen densities from drawable-ldpi
to drawable-xxxhdpi
.
I've also found that if I hardcode b.setImageResource(2131165284);
based on the log lines, the ImageButton
displays the same image for both buttons in both debug and release mode, which is expected behavior.
How come dynamically setting the resource doesn't work in release mode?
EDIT: Ok, I think I found the problem. My release build mode has the following properties:
release {
minifyEnabled true
shrinkResources true
debuggable true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
signingConfig = signingConfigs.release
}
When I disabled shrinkResources
, by commenting it out, the images appeared again. It seems that, based on "minifyEnabled" vs "shrinkResources" - what's the difference? and how to get the saved space?, ProGuard detects that the resources I depend, the .png
drawables, on aren't used because they're dynamically requested and so shrinkResources
removes them entirely.
Does anyone know how to get around this?
Ok, I found the answer. The solution that worked for me was to use tools:keep
from https://developer.android.com/studio/write/tool-attributes#toolskeep to purposefully keep those resources even with shrinkResources
set to true
.