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

标签 android out-of-memory android-bitmap

我正在应用程序中的 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();
            }
        });

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

我尝试回收位图-

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

但是上面的代码总是在bitmapDrawable的值中给出null。如何修复此内存不足异常?

附注图像可绘制的最大大小为 80kb

最佳答案

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

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

现在这在平板电脑上可能没问题,但在可能有 64 MB 堆空间的旧手机上,您可能很容易遇到 OutOfMemoryExceptions。

那么你能做什么呢?

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

  2. 使用不同的位图配置。默认为 RGB_8888,即每个 channel 8 位 (ARGB) = 32 位。如果您不需要 Alpha channel (透明度),并且图像不必具有超高品质,您应该尝试一下 RGB_565。它的质量下降非常小,但几乎无法察觉。作为返回,它消耗的内存减半(5 + 6 + 5 = 每像素 16 位)。

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

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

    因此,虽然该图像在大型平板电脑上会占用 8.29 Mb 堆空间,但在旧手机上只会占用 921 Kb,这正是我们想要的。 不过,它确实会增加 APK 大小,因为现在它包含 4 个图像,而不是一个。

关于android - 在 ImageView 中设置图像时内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33279223/

相关文章:

android - 如何从新网站安装 sl4a?

java - 使用 log4j 显示响应的堆内存问题

multithreading - 如何保持在内存的范围内

android - 如何在 Android 上的 Glide 中设置位图图像

android - LifeCycleAware Fragment 中的 fragment 生命周期事件

android - android广播接收器中的StartActivity

android textview settext 显示空指针异常

javascript - OpenLayers3 WMTS 内存不足错误

android - 如何使用 Picasso 将位图加载到 ImageView 中

android - 如何设置填充父级的位图大小?