关于android使用大量Drawable发生OOM的解决方案

1.界面比较多,并且很多界面的背景图片不一样;

2.涉及到换肤功能,定义多种皮肤,皮肤的资源不是使用color 而是图片资源;

以上两种情况,如果不注意合理释放内存,将会发生OOM。我们在android程序中,无论是使用layout布局设置了背景还是使用了setBackgroundResource 设置背景,在大屏幕手机上特别是在三星的大屏幕手机,爆oom的几率更大。

网上很多例子都是使用以下方式去释放内存:

    View view = findViewById(R.id.page_bg);
    BitmapDrawable bitmapDrawable = (BitmapDrawable) view.getBackground();
    view.setBackgroundResource(0);
    bitmapDrawable.setCallback(null);
    Bitmap bitmap = bitmapDrawable.getBitmap();
    if(bitmap != null && !bitmap.isRecycled()){
        bitmap.recycle();
        bitmap = null;
    }
    System.gc();    

然而使用该方法后却存在另外一个潜在的致命问题:Canvas: trying to use a recycled bitmap(即使用了一个已经释放的Bitmap来绘制界面)。

情况1:A界面中使用了a.png图片,然后做了跳转,finish了A界面,finish的时候,使用了以上代码释放了内存,然后再次进入A界面,极有可能出现该问题。

情况2:A界面中使用了a.png图片,然后在B界面也使用了a.png, A界面没有finish,B界面使用了finsh,并且使用上面同样的方式释放了内存。然后我们正常情况下,A界面会经历onResume的方式来显示,可是这个时候,我们的a.png在内存中已经释放了,此时就会出现上面的错误。

解决方案:

无论你是在xml中布局使用了:android:background;还是在java代码中调用了:setBackground(background);setBackgroundDrawable(background);setBackgroundResource(resid)的方式去设置了背景图片。

使用的时候,请调用一下对应的方法:
setBackgroundResource和android:background→setBackgroundResource(0);

setBackgroundDrawable(background)→setBackgroundDrawable(null);

setBackground(background)→setBackground(null);

然后在onDestory中调用System.gc();

posted @ 2014-10-22 19:03  张小宝的博客  阅读(4535)  评论(0编辑  收藏  举报