Android本地图片加载展示而不容易OOM的办法
一、读取图片时进行压缩
话不多说先上代码:
public static Bitmap getBitmapByFile(String path, int width, int height) { BitmapFactory.Options option = new BitmapFactory.Options(); option.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, option); option.inSampleSize = Math.max(1, Math.min(option.outWidth / width, option.outHeight / height)); option.inJustDecodeBounds = false; return BitmapFactory.decodeFile(path, option);}
先补充一点,有时候看网上一些人把Math.min(option.outWidth / width, option.outHeight / height)这句中两个除法改成浮点数运算,然后取完最小值后转成int型,不过用处不大,因为inSampleSize函数只会取值2的次方值,所以5和5.5都会取4,浮点运算并不会把整除得出来的7变成大于8的结果。
最近遇到一个问题,从相册读取图片进行展示并上传,刚开始做需求时,因为 (lan) 没做图片压缩,所以喜闻乐见的发生了读取图片过多时OOM一下,只能说现在相机真好,相片的图片分辨率真大。所以,没什么好说的,开发阶段遇到的问题绝不能拖到测试阶段修改,上网找解决方案。
1. BitmapFactory.Options的inJustDecodeBounds属性。
这个属性可以决定是否返回bitmap,如果inJustDecoedBounds设置为true的话,解码bitmap时可以只返回其高、宽和Mime类型,而不必为其申请内存,从而节省了内存空间。利用这个属性就可以先获取到要读取图片的大小,而不会将一个庞大的图片加载到捉急的内存中。
2. BitmapFactory.Options的inSampleSize属性。
这个属性有人说是采样率,也就是按多少比例读取原始图片,虽然具体的采样方式不是很懂,但是理解成缩放属性就容易懂了。我们只要计算图片大小和控件尺寸的比例值,取合理的那个就ok。比如代码中,取了高度和宽度中小的那个值,不过取最小的话在面对长图如万里江山图清明上河图海底两万里等,图片读取出来的大小还是会比较大,用个简单方式去区分取最大值还是最小值的办法,就是imageview的scaleType,centerCrop取最小值,fitCenter取最大值。
还有一点可能需要注意的,就是inSampleSize的取值,只会取值2的次方值,这个次方不仅包括自然数,也包括负整数,由于存在加载小图的可能,为了不让本来小小的图读到内存中时变成大怪物,所以加一个Math.max(1, N)来保证最小取1。
二、及时回收图片内存。
我现在负责的这个项目图片加载地方很少,所以没有用到ImageLruCache,不过再一个以前的项目中用到过它,所以也在这里记一下,网上介绍它的文章也很多,所以就提一下,不多介绍,如果下次项目中用到这个缓存的时候,我再来补全这个的用法以及介绍。
所以,bitmap.recycle()方法请了解一下~在图片加载不多的项目中也要及时的回收图片哟~
更多相关文章
- Android 相册选择照片或拍照获取图片系统6.0及7.0实现
- android Gallery 仿iPhone 图片滑动
- Android 图片裁剪功能实现详解(类似QQ自定义头像裁剪)
- 【android】可放大缩小图片位置点击位置获取
- Android 将drawable下的图片转换成bitmap、Drawable