OOM问题(bitmap背景用完回收)

时间:2022-02-22 20:56:32
转载的作者:SpringSky 出处:http://blog.csdn.net/springsky_/article/details/25212419blog:http://blog.csdn.net/springsky_本文版权归作者和CSDN共有因为是转载的,所以把作者出处放到最上面了,谢谢前辈的分享!
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();

 

 

情况1、 你A界面中使用了a.png图片,然后做了跳转,finish了A界面,finish的时候,你使用了一下的代码释放了内存:

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

 

然后再次进入A界面,极有可能出现该问题。

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

 

05-07 07:00:37.991: E/AndroidRuntime(6988): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@417fc280

 

看着字面很简单,很容易理解,实际中找到问题的所在却不是容易的一件事。

 

也许,你在这一刻是否已经抓狂了,难道就没办法来释放内存来解决潜在的oom问题?
答案是否。像google这样的大公司,他们提供的api,考虑的潜在问题比我们正常程序员考虑的还要深入N倍。

个人从新阅读了相关的api,得出了一下解决办法来释放内存,解除我们潜在的oom情况
 

无论你是在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();
以上的代码,我们修改为:

View view = findViewById(R.id.page_bg);
		view.setBackgroundResource(0);
		System.gc();



我们在看看我们的logcat的结果:

 

 

05-07 07:29:18.941: D/dalvikvm(7598): GC_FOR_ALLOC freed 27K, 65% free 9791K/27452K, paused 43ms, total 58ms
05-07 07:29:18.970: I/dalvikvm-heap(7598): Grow heap (frag case) to 13.203MB for 3686416-byte allocation
05-07 07:29:19.041: D/dalvikvm(7598): GC_FOR_ALLOC freed 83K, 52% free 13308K/27452K, paused 72ms, total 72ms
05-07 07:29:19.140: D/dalvikvm(7598): GC_CONCURRENT freed 以上的界面和我们调用了手动释放的方式是不是一样? 呵呵,反复测试多次,看看还会不会导致java.lang.RuntimeException: Canvas: trying to use a recycled bitmap

 

实际上,我们的程序不会再出现上面的问题了,并且解决了oom得潜在危机。如此的简单,如此的便捷。

 

同理:如果我们在程序中,使用了ImageView的话, 我们也可以使用
imageView.setImageResource(0); 这种方式,来释放我们设置的android:src或者bitmap等等。

 

那么,关于图片的oom可能潜在的问题,我们告一段落,从这次的经历,让我更加的深入的了解java语言的内存回收机制,总结一句话:尽可能的让系统去释放内存,我们只负责标示需要释放的内存。通俗点:我们只是标记需要杀的人,谁来杀,就让杀手看着办。


作者:SpringSky
出处:http://blog.csdn.net/springsky_/article/details/25212419
blog:http://blog.csdn.net/springsky_