在 ImageView 中设置图像时内存不足

OutOfMemory while setting image in ImageView

我正在我的应用程序的 4 个不同位置设置帮助屏幕图像。 activity代码如下-

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.help_list);
        int screenType = getIntent().getIntExtra("screenName", 0);
        ImageView imageView = (ImageView) findViewById(R.id.help_image);

        switch (screenType) {
            case 1:
                imageView.setImageResource(R.drawable.help0);
                break;
            case 2:
                imageView.setImageResource(R.drawable.help1);
                break;
            case 3:
                imageView.setImageResource(R.drawable.help2);
                break;
            case 4:
                imageView.setImageResource(R.drawable.help3);
                break;
        }

        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

此代码在大多数设备上都能成功执行,但在某些设备(例如三星)上,应用程序会因内存不足异常而崩溃。

我试过回收Bitmap-

   BitmapDrawable bitmapDrawable = ((BitmapDrawable) imageView.getDrawable());
    if (bitmapDrawable != null) {
        bitmapDrawable.getBitmap().recycle();
    }

但是上面的代码总是在bitmapDrawable的值中给出null。我该如何解决这个 OutOfmemory 异常?

P.S。可绘制图像的最大尺寸为 80kb

我觉得你的问题描述的很好here

或者您可以通过 photoshop 将图像尺寸更改为 50x50 等

图片的像素大小是多少?由于图像存储在 java 堆中,因此不会压缩它们。这意味着位图的每个像素在堆中最多可以占用 32 位 = 4 个字节。 因此,对于尺寸为 1920 x 1080 的图像(也许您还针对大分辨率平板电脑),即:

1920 x 1080 x 4 bytes = 8294400 bytes, 8.29 megabytes.

现在这在平板电脑上可能没问题,但在可能有 64 兆字节堆 space 的旧 phone 上,您可能很容易 运行 进入 OutOfMemoryExceptions。

那你能做什么?

  1. 如果您只针对 phones,您可以将图像调整为更小的尺寸吗?这主要是基于反复试验,也取决于图像的使用(模糊背景图像VS具有重要细节的地图图像)。

  2. 使用不同的位图配置。默认是RGB_8888,也就是每个通道8位(ARGB)=32位。如果您不需要 alpha 通道(透明度),并且图像不需要超高质量,您应该尝试 RGB_565。它的质量下降非常小,但几乎不明显。在 return 中,它消耗了一半的内存(5 + 6 + 5 = 每个像素 16 位)。

  3. 最重要的修复:您可以为不同的屏幕密度提供不同的图像。所以这是一个例子。假设我们要使用来自计算的全高清图片。 对于较小的屏幕,我们将其缩小以节省内存。有针对不同密度缩小图像的工具,请参阅 this question。 按照密度准则,您可以将以下具有尺寸的图像放在给定目录中:

    • drawable-xxhdpi: 1920x1080
    • drawable-xhdpi: 1280x720
    • drawable-hdpi: 960x540
    • drawable-mdpi: 640x360

    因此,虽然图像在大型平板电脑上会占用 8.29 Mb 堆 space,但在较旧的 phone 上只会占用 921 Kb,这正是我们想要的。 不过,它确实伴随着增加 APK 大小的成本,因为现在它包含 4 张图片而不是一张。