zoukankan      html  css  js  c++  java
  • 【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     }
  • 相关阅读:
    pthread_mutex_init函数与pthread_mutexattr_init函数
    DPDK收发包全景分析
    Linux Bond的原理及其不足
    Cisco VPP启动流程
    组网基础之深入解析二层组播
    vpp命令总结
    全面挖掘Java Excel API 使用方法
    MySQL的varchar定义长度到底是字节还是字符
    MYSQL 用户管理
    MySql中的变量定义
  • 原文地址:https://www.cnblogs.com/lqminn/p/2731265.html
Copyright © 2011-2022 走看看