Search code examples
androidandroid-imagebutton

Android button ImageButton not displaying image when run in release mode


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.

enter image description here

However, when I run the app in release mode the ImageButton doesn't display the drawable:

enter image description here

I create and populate my ImageButtons 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.

enter image description here

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?


Solution

  • 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.

    See also https://stackoverflow.com/a/50703322/1489726