android报错记录及解决--Bitmap加载时,报bitmap size exceeds VM budget

来源:互联网 发布:android开发内存优化 编辑:程序博客网 时间:2024/04/27 23:23

报错描述:

  用Bitmap加载图片资源时,报错java.lang.OutOfMemoryError: bitmap size exceeds VM budget

原因分析:

  android系统限制,只给图片分配8M内存,超过就蹦。图片虽然几十K,可能是压缩格式,转换成BitMap就是本来大小

解决办法:

  1、Android模拟器在设置时可以将Max VM application heap size值设大一点,我这里默认是16,改到60

    

  2、图形对象优化,这里要说的是Android上的Bitmap对象销毁,可以借助recycle()方法显示让GC回收一个Bitmap对象,

     通常对一个不 用的Bitmap可以使用下面的方式,如 

  

1 if(bitmapObject.isRecycled()==false) //如果没有回收  2          bitmapObject.recycle();  

延伸学习:

  设置恰当的inSampleSize可以使BitmapFactory分配更少的空间以消除该错误,我们要将图片按照固定大小取缩略图,一般取缩略图的方法是使用      BitmapFactory的decodeFile方法,然后通过传递进去 BitmapFactory.Option类型的参数进行取缩略图,在Option中,属性值inSampleSize表示缩略图大小为原始图片大小的几分之一,即如果这个值为2,则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4

1         BitmapFactory.Options opts =  new  BitmapFactory.Options();2         opts.inSampleSize =  4 ;3         Bitmap bitmap = BitmapFactory.decodeFile(imageFile, opts);

  然而,如果我们想取固定大小的缩略图就比较困难了,比如,我们想将不同大小的图片去出来的缩略图高度都为200px,而且要保证图片不失真,那怎么办?我们总不能将原始图片加载到内存中再进行缩放处理吧,要知道在移动开发中,内存是相当宝贵的,而且一张100K的图片,加载完所占用的内存何止 100K?

  可以通过设置Options中有个属性inJustDecodeBounds来处理,如果该值设为true那么将不返回实际的bitmap不给其分配内存空间而里面只包括一些解码边界信息即图片大小信息,那么相应的方法也就出来了,通过设置inJustDecodeBounds为true,获取到outHeight(图片原始高度)和 outWidth(图片的原始宽度),然后计算一个inSampleSize(缩放值),然后就可以取图片了,这里要注意的是,inSampleSize 可能小于0,必须做判断。

复制代码
 1 BitmapFactory.Options options = new BitmapFactory.Options(); 2         options.inJustDecodeBounds = true; 3         // 获取这个图片的宽和高 4         Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/test.jpg", options); //此时返回bm为空 5         options.inJustDecodeBounds = false; 6          //计算缩放比 7         int be = (int)(options.outHeight / (float)200); 8         if (be <= 0) 9             be = 1;10         options.inSampleSize = be;11         //重新读入图片,注意这次要把options.inJustDecodeBounds 设为 false哦12         bitmap=BitmapFactory.decodeFile("/sdcard/test.jpg",options);13         int w = bitmap.getWidth();14         int h = bitmap.getHeight();15         System.out.println(w+"   "+h);16         ImageView iv=new ImageView(this);17         iv.setImageBitmap(bitmap);
复制代码

这样我们就可以读取较大的图片而不会内存溢出了。

==================夫夷以近,则游者众,险以远,则至者少!==================
0 0