为什么这个图像切换代码有内存泄漏?(Why this image-switching code ha

2019-10-17 04:28发布

我写一个简单的Android应用程序,其使用ImageView来显示图像。 当点击一个按钮,它会根据当前图像上产生一个新的位图,并更换旧的。

我使用的图像并不大:220 X 213。

但在模拟器,当我按一下按钮第五次,它会抛出一个错误:

 java.lang.OutOfMemoryError: bitmap size exceeds VM budget

我读过一些文章:

  1. java.lang.OutOfMemoryError:位图大小超过VM预算-安卓
  2. http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/
  3. http://android-developers.blogspot.de/2009/01/avoiding-memory-leaks.html

但仍然没有解决我的问题。

我的代码是:

public class MyActivity extends Activity {
    private Bitmap image;
    private ImageView imageView;
    private Button button;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        this.button = (Button) findViewById(R.id.button);
        this.imageView = (ImageView) findViewById(R.id.image);


        this.image = BitmapFactory.decodeResource(getResources(), R.drawable.m0);
        this.imageView.setImageBitmap(image);

        this.button.setOnClickListener(new View.OnClickListener() {
            private int current = 0;

            @Override
            public void onClick(View view) {
                Bitmap toRemove = image;
                Matrix matrix = new Matrix();
                matrix.setRotate(30, 0.5f, 0.5f);
                image = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), matrix, true);
                imageView.setImageBitmap(image);

                if (toRemove != null) {
                    toRemove.recycle();
                }
            }
        });
    }
}

你可以看到我已经调用toRemove.recycle()去除图像上。 但似乎没有影响。


更新:

因为当我按一下按钮第五次(不是第一次)的错误只发生后,我们可以看到的图像尺寸是没有问题的。 而在我的代码,我试图生成一个新的后释放的旧形象,所以我觉得旧形象还没有被释放正确。

我援引toRemove.recycle()它是释放一个图像的正确方法是什么? 或者我应该使用什么东西?


最后:

埃米尔是正确的。 我添加了一些代码,记录大小,你可以看到它每一次增加:

08-28 13:49:21.162: INFO/image size before(2238): 330 x 320
08-28 13:49:21.232: INFO/image size after(2238): 446 x 442
08-28 13:49:31.732: INFO/image size before(2238): 446 x 442
08-28 13:49:31.832: INFO/image size after(2238): 607 x 606
08-28 13:49:34.622: INFO/image size before(2238): 607 x 606
08-28 13:49:34.772: INFO/image size after(2238): 829 x 828
08-28 13:49:37.153: INFO/image size before(2238): 829 x 828
08-28 13:49:37.393: INFO/image size after(2238): 1132 x 1132

Answer 1:

我不知道Bitmap.createBitmap()很是如何工作的,但考虑到误差与“位图大小”做

java.lang.OutOfMemoryError: bitmap size exceeds VM budget

我将假定图像的大小与每个点击增加。 因此,发生在5日点击错误。

我建议,尺寸的增加是与旋转矩阵做。 当图像被旋转看来,它不是裁剪旋转的图像到图像的宽度和高度,而是增加图像的尺寸。

你将不得不尝试你想要的W / H范围内操纵旋转一些替代方法。

答案(二下)对这个问题说明了如何裁剪旋转的图像,如果你愿意的话。 Android的:如何在一个中心点旋转一个位图

RectF rectF = new RectF(0, 0, source.getWidth(), source.getHeight());
matrix.mapRect(rectF);


文章来源: Why this image-switching code has memory leak?