Android 按钮 ImageButton 在 运行 处于释放模式时不显示图像

Android button ImageButton not displaying image when run in release mode

我正在尝试使用 ImageButton 来显示资源,.png 作为可点击按钮。当我 运行 我的应用程序处于调试状态时,ImageButton 正确获取图像。

但是,当我 运行 应用程序处于发布模式时 ImageButton 不显示可绘制对象:

我以编程方式创建并填充我的 ImageButtons:

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

        }
    }

在发布模式下 运行 时我的日志输出是:

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

下面是 运行在调试模式下运行应用程序的日志:

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

似乎在两种模式下都发现了相同的可绘制对象,但出于某种原因,它们不会在发布模式下显示。这是怎么回事?

我已验证从 drawable-ldpidrawable-xxxhdpi 的所有屏幕密度都存在可绘制对象。

我还发现,如果我根据日志行对 b.setImageResource(2131165284); 进行硬编码,ImageButton 会在调试和发布模式下为两个按钮显示相同的图像,这是预期的行为。

为什么动态设置资源在发布模式下不起作用?

编辑:好的,我想我找到了问题所在。我的发布构建模式具有以下属性:

        release {
            minifyEnabled true
            shrinkResources true
            debuggable true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
            signingConfig = signingConfigs.release
        }

当我禁用 shrinkResources 时,通过注释掉它,图像又出现了。似乎,基于 "minifyEnabled" vs "shrinkResources" - what's the difference? and how to get the saved space?,ProGuard 检测到我所依赖的资源 .png 可绘制对象未被使用,因为它们是动态请求的,因此 shrinkResources 将它们完全删除。

有谁知道如何解决这个问题?

好的,我找到了答案。对我有用的解决方案是使用 https://developer.android.com/studio/write/tool-attributes#toolskeep 中的 tools:keep 有目的地保留这些资源,即使 shrinkResources 设置为 true

另见

您是否检查过是否因为图像占用了太多资源而发生这种情况?图片文件有多大?它与按钮的尺寸相同吗?

Android不会让release模式的app占用那么多资源。我建议您使用像 Picasso 这样的库来设置 ImageButton 上的图像资源。 Picasso 将处理屏幕和按钮大小本身的资源大小调整。

而且它也非常易于使用。

Picasso.get().load(R.drawable.your_image_resource).into(yourImageButton);

https://square.github.io/picasso/