关于位图:Android BitmapFactory.decodeResource out of memory if used more than once

Android BitmapFactory.decodeResource out of memory if used more than once

我正在重新编写一个 Android 应用程序,其中每个活动(有几个)显示一个背景图像。用户可能会更改此图像,因此我已完成以下操作:

  • 创建 MyAppApplication(扩展应用程序),在每个活动的 onCreate() 中设置对其的引用。
  • MyAppApplication 有一个公共的 BitmapDrawable,它在启动时应用于背景。
  • 每个活动都会监听 SharedPreferences 中的变化,并在这些变化时重新加载背景图像。
  • 这是我用来设置图像的部分代码,基于 http://developer.android.com/training/displaying-bitmaps/load-bitmap.html:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Bitmap bitmap = decodeBitmap(R.drawable.background_image, screen_width, screen_height);
    }
    public BitmapDrawable backgroundImage = new BitmapDrawable(bitmap);

    public Bitmap decodeBitmap(int resId, int reqWidth, int reqHeight)
    {
      // First decode with inJustDecodeBounds=true to check dimensions
      final BitmapFactory.Options options = new BitmapFactory.Options();
      options.inJustDecodeBounds = true;
      BitmapFactory.decodeResource(getResources(), resId, options);

      // Calculate inSampleSize
      options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

      // Decode bitmap with inSampleSize set
      options.inJustDecodeBounds = false;
      return BitmapFactory.decodeResource(getResources(), resId, options); // crashes here
    }

    然后,在活动中,我将背景设置为 backgroundImage。

    应用程序第一次启动时这是可行的,但如果更改了共享首选项,则应用程序会尝试再次解码资源,并且应用程序会在上面标记的点崩溃。请问我可以做些什么来避免这种情况?


    每次使用完位图后,都应该释放它们,因为它们会占用大量内存。

    在 onDestroy() 中你应该这样写:

    1
    2
    bitmap.recycle();
    bitmap = null;

    您也应该在停止使用位图时调用这些行。


    我会接受原始答案,因为确实需要将位图设置为 null 是正确的。问题是我把它设置在错误的地方。

    读取位图时,应用程序中出现错误,但这是因为活动中的位图。所以,我必须在每个活动中都这样做来修复它:

    1
    2
    layout.setBackgroundDrawable(null);
    layout.setBackgroundDrawable(myApplication.getBackground());