【Android】Bitmap的管理

 

与图片有关的软件免不了要做Bitmap的管理,要不然很可能就会发生OutOfMemory(OOM)的错误,致使程序崩溃。引起这种现象的原因无非是:

1.长期保持对某个对象或数据的引用,导致java的垃圾回收器不能回收不再使用的内存空间;

2.正在使用的有效对象占用内存空间大,导致多个有效对象生成时,吃完程序所分配的内存; 

一般会报这种错误:java.lang.OutOfMemoryError: bitmap size exceeds VM budget,这是因为,android系统中读取位图Bitmap时.分给虚拟机中图片的堆栈大小只有8M。所以不管是如何调用的图片,太多太大虚拟机肯定会报这个错误。(对于实际的机器来说,这个内存分配是不是很大?)

而像相册这样子的应用,最好的效果是:

1)将图片(单个资源)缩小到适当的大小,以便于同时加载多张图片;

2)就算缩小到适当的大小,我们也不能将所有图片的引用同时保存在内存中,这时候需要将部分的图片释放;

遇到这种问题的解决方案是:缩小图片+回收资源的方式,来优化内存:

尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source,decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间。如果在读取时加上图片的Config参数,可以跟有效减少加载的内存,从而跟有效阻止抛out of Memory异常。

另外,decodeStream直接拿的图片来读取字节码了, 不会根据机器的各种分辨率来自动适应,使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源,否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。

1)缩小图片的方式:

1 InputStream is = this.getResources().openRawResource(R.drawable.pic1);
2 BitmapFactory.Options options=new BitmapFactory.Options();
3 options.inJustDecodeBounds = false;
4 options.inSampleSize = 10;   //width,hight设为原来的十分一
5 Bitmap btp =BitmapFactory.decodeStream(is,null,options);

2)回收图片的方式:

1 if(!bmp.isRecycle() ){
2     bmp.recycle()   //回收图片所占的内存
3     system.gc()  //提醒系统及时回收
4 }

缓存:加载图片的时候首先检测是否被缓存然后再去动作

1  //用来存放图片的缓存
2  HashMap<Integer, Bitmap> bitmapCache = new HashMap<Integer, Bitmap>();
3  //如果没有图片,或者已经存在
4  if(bitmapCache.isEmpty() || !AppConst.bitmapCache.containsKey(position)){
5        bitmapCache.put(position, bm);
6        System.out.println("-----------inset cache---------");
7  }

定义FreeBitmap函数,在activity结束的时候,调用FreeBitmap函数,回收map中的资源

 1    private void FreeBitmap(HashMap<Integer, Bitmap> cache){
 2         if(cache.isEmpty()){
 3             return;
 4         }
 5         for(Bitmap bitmap:cache.values()){
 6             if(bitmap != null && !bitmap.isRecycled()){
 7                 bitmap.recycle();
 8                 System.out.println("=============recycle bitmap=======");
 9             }
10         }
11         cache.clear();
12     }
posted @ 2012-10-19 16:36  大脚印  阅读(616)  评论(0编辑  收藏  举报