可绘制与单个可重用位图更好的内存?

时间:2011-08-12 18:37:36

标签: android memory bitmap drawable recycle

据我所知(并非我是正确的)当应用程序完成后,通常会从内存中正确删除Drawable。但是,位图需要手动回收,有时甚至会编写一个特殊的类来正确处理它们。 我的问题是,关于记忆和泄漏,简单地坚持使用Drawables 是更有利的:

myView.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image));
myView1.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image1));
myView2.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image2));

而不是像Bitmaps那样:

Bitmap tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image);
myView.setImageBitmap(tmpBitmap);

tmpBitmap.recycle();
tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image1);
myView1.setImageBitmap(tmpBitmap);

tmpBitmap.recycle();
tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image2);
myView2.setImageBitmap(tmpBitmap);
tmpBitmap.recycle();

我当然也读过你必须小心bitmaps上的recycle()方法,因为它们可以在使用时删除吗?似乎这些问题不断出现在不同的形式,但我无法真正得到任何人的直接答案。一个人说重复使用Bitmap并在每次使用后回收,其他人说使用Drawables和unbindDrawables()方法(这是我一直在使用的):

private void unbindDrawables(View view) {
    if (view.getBackground() != null) {
        view.getBackground().setCallback(null);
    }
    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            unbindDrawables(((ViewGroup) view).getChildAt(i));
        }
        ((ViewGroup) view).removeAllViews();
    }
}

任何适用的见解都会受到高度赞赏。感谢

2 个答案:

答案 0 :(得分:9)

位图不需要手动回收。它们像Drawables和其他对象一样被垃圾收集。同样,除非在特定情况下,否则不需要取消绑定drawable。你似乎读了很多误导性的信息。

在某些情况下,回收位图和取消绑定drawable非常有用(例如,如果您的应用操作大量位图数据或者以静态方式存储drawable。)

您在问题开头显示的两个示例是等效的。如果直接加载drawable,将代表您加载位图。如果手动加载位图并在ImageView上设置它们,则代表您将它们包含在drawable中。

使用第一个解决方案,因为它更简单,在您真正需要它们之前不必担心解除绑定和其他内存管理技术。

答案 1 :(得分:8)

我支持罗曼的建议,但我不确定你的问题是否解决了你的实际问题。我不知道你如何处理对你的视图的引用。也许你只是在你的应用程序中有内存泄漏? Android中的大量内存泄漏与Context有关。当Drawable附加到View时,View会被设置为Drawable上的回调。

TextView myView = new TextView(this);
myView.setBackgroundDrawable(getDrawable(R.drawable.my_bitmap));

在上面的代码段中,这意味着Drawable引用了TextViewActivity本身引用了Contextnull)根据你的代码提供了很多东西。

如果没有查看更多代码,我猜您在Activity被销毁时将存储的drawables的回调设置为{{1}},从而走在正确的轨道上。