天天看点

解决Bitmap导致的内存溢出问题

最近在做一个手机笔记本,遇到添加大量的本地图片到GridView以及经常切换到多图片的Activity,出现OOM的问题,现在总结一下解决的办法。

首先OOM出现的原因很大程度上是很多Bitmap对象的使用没有进行内存是释放,另一个是Activity内加载的图片过大,导致占用的内存超出了系统分配给每个应用程序的上限。这样的直接后果就是,软件在使用着的时候会越来越卡,然后没有任何提示就退出了。而解决这样的问题就可以根据原因来逐个击破了。

1、内存的释放,定义的Bitmap对象为成员变量的话,在Activity的onDestory()方法应该进行相应的内存释放,并提醒系统进行垃圾回收(虽然JVM会自动垃圾回收,但做到这一步更加保险)。

if(bitmap!=null && !bitmap.isRecycled()){
bitmap.recycle();
bitmap = null;
}
System.gc();
           

2、如果加载的图片比较大,而且是通过BitmapFactory.decodeFile()等方式加载的图片资源,应该采用图片缩放的方式对图片进行压缩处理。BitmapFactory有个options参数可以在加载图片的时候设置缩放的比例

(1)设置options.inJustDecodeBounds为true,获取到outHeight(图片的原始高度)和outWidth()(图片的原始宽度)

· (2)计算inSampleSize的值,这个为缩放值,例如2表示缩小为原来的1/2,该值可以通过直接设置或者自己通过计算按一定的比例得到

BitmapFactory.options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
int scale = (int)(options.outHeight/(float)200);//我们只用高度或宽度计算均可
if(scale<=0){
scale = 1}
options.inSampleSize = scale;
Bitmap bitmap = BitmapFactory.decodeFile(path,options);
           

3、如果在要加载很多bitmap的场合,我们也可以让Bitmap数维持在一个值内,超出这个值后将前面的先回收内存。例如我们可以将bitmap对象创建的时加入一个List,当List.size()超过8的话,就将第一个bitmaph回收。

4、ListView等组件使用网络图像的时候,我们可以将图片下载到本地保存成file,判断本地没有该图片再从网络上异步下载。

继续阅读