关于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();