1. 大图片的加载显示(避免OOM问题):
1). 问题: 如果将大图片加载到内存中来显示, 可能会导致
内存溢出(OOM)
2). 解决思路: 对图片进行
压缩加载(本质上只是读取了图片文件的部分数据)
3). 具体办法:
①. 得到图片的宽高的方式:
|
注意: 为了避免OOM异常,最好在解析每张图片的时候都先检查一下图片的大小,
除非你非常信任图片的来源,保证这些图片都不会超出你程序的可用内存
②. 计算取样比例的方式:
|
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// 源图片的高度和宽度
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// 计算出实际宽高和目标宽高的比率
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
// 一定都会大于等于目标的宽和高。
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
|
注意: 如果inSampleSize=3, 表示 宽和高上只读取原来数据的1/3, 这样整体大小压缩为原来的1/9
③. 整体处理:
|
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// 第一次解析将inJustDecodeBounds设置为true,只获取图片宽,高大小
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; //不会加载整个图片文件
BitmapFactory.decodeResource(res, resId, options);
// 调用上面定义的方法计算inSampleSize值
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// 使用获取到的inSampleSize值再次解析图片
options.inJustDecodeBounds = false;
//会根据inSampleSize加载图片的部分数据到内存
return BitmapFactory.decodeResource(res, resId, options);
}
|
调用代码如下:
|
2. 缓存图片对象
1). 在内存中缓存图片对象(Bitmap),
不要直接用Map<String, Bitmap>类型的容器, 因为这样会导致bitmap对象太多太大时而没有去释放, 最终
导致OOM
2). 在Android2.3之前, 一般都用
Map<String, SoftReference<Bitmap>>结构容器来缓存Bitmap对象, 这样在内存不太充足时, 垃圾回收器会将软引用对象释放.
但从2.3开始, 垃圾回收器可能在正常情况下就回收软引用对象, 这样会降低缓存的效果
3). Android的v4兼容包中提供了
LruCache来做缓存容器, 它的基本原理为:
把最近使用的对象用强引用存储在 LinkedHashMap 中,并且把最近
最少使用的对象在缓存值达到预设定值之前从内存中移除
|
3. 主动释放bitmap对象
if(!bmp.isRecycle() ){ bmp.recycle() // 回收图片所占的内存 system.gc() // 提醒系统及时回收 } |
4. 设置加载图片的色彩模式:
Android中有四种,分别是:
ARGB_8888:每个像素占用4byte内存(默认)
ARGB_4444:每个像素占用2byte内存(透明度&颜色, 失真严重, 不推荐使用)
RGB_565:每个像素占用2byte内存(颜色, 没有透明度值)
ALPHA_8:每个像素占用1byte内存()
默认的模式显示的图片质量是最高的, 但也是占用内存最大的, 而如果使用RGB_565模式, 占用的内存就会减少为1/2, 但显示效果差别不明显
|
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_4444;
Bitmap img = BitmapFactory.decodeFile("/sdcard/1.png", options);
|
本文介绍Android中处理大图片加载及内存优化的方法,包括压缩图片、使用LruCache缓存、主动释放Bitmap对象等技巧,有效避免OOM问题。

被折叠的 条评论
为什么被折叠?



