在安卓开发中经常会加载各类图片,图标等,但是关注内存消耗的小伙伴们会发现:本来不大的一张图片加载后会使app占用的内存增大几Mb甚至十几Mb的内存,这是怎么回事呢.下面我将会对此通过一个测试来给出答案:
1.普通加载图片的方法是
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fast,opts);
通过一段代码的测试,就能发现这种加载模式的弊端:
StringBuilder sb = new StringBuilder();
sb.append("加载图片前的内存占用:"+Formatter.formatFileSize(this, Runtime.getRuntime().totalMemory()));
mDesc.setText(sb.toString());
//普通加载图片
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fast);
mImg.setImageBitmap(bitmap);
sb.append("\r\n");
sb.append("加载图片后的内存占用:"+Formatter.formatFileSize(this, Runtime.getRuntime().totalMemory()));
mDesc.setText(sb.toString());
普通加载后,app内存占用多了8.8Mb;
2.手动设置采样比的压缩加载方式
StringBuilder sb = new StringBuilder();
sb.append("加载图片前的内存占用:"+Formatter.formatFileSize(this, Runtime.getRuntime().totalMemory()));
//获取加载图片前的app中占内存的大小
mDesc.setText(sb.toString());
Options opts = new Options();
//设置采样比
opts.inSampleSize = 2;
//带压缩比例的加载图片
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fast,opts);
mImg.setImageBitmap(bitmap);
sb.append("\r\n");
sb.append("加载图片后的内存占用:"+Formatter.formatFileSize(this, Runtime.getRuntime().totalMemory()));
mDesc.setText(sb.toString());
加载后,app内存占用多了2.2Mb;
3.按科学压缩比加载图片
StringBuilder sb = new StringBuilder();
sb.append("加载图片前的内存占用:"+Formatter.formatFileSize(this, Runtime.getRuntime().totalMemory()));
//获取加载图片前的app中占内存的大小
mDesc.setText(sb.toString());
Options opts = new Options();
//设置只加载图片的边界参数 宽高尺寸
opts.inJustDecodeBounds = true;
//带压缩比例的加载图片
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fast,opts);
//设置科学的采样比(获取图片的宽度和高度)
opts.inSampleSize = caculateSampleSize(opts.outWidth,opts.outHeight);
//关闭标记 解析真实的图片
opts.inJustDecodeBounds = false;
//按科学的采样比加载图片
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fast,opts);
mImg.setImageBitmap(bitmap);
sb.append("\r\n");
sb.append("加载图片后的内存占用:"+Formatter.formatFileSize(this, Runtime.getRuntime().totalMemory()));
mDesc.setText(sb.toString());
加载后,app内存占用只多了0.04Mb;.
此处如果设置渲染模式为:opts.inPreferredConfig = Config.RGB_565;时,内存占用会更小.但是Config.RGB_565模式的渲染会丢失图片的透明色彩,所以建议在加载小图标时可用此种渲染模式,其他时候的图片加载展示还是用默认的Config.ARGB_8888模式.
4.下面给出计算并获取合理的采样比的方法的代码:
private int caculateSampleSize(int outWidth, int outHeight) {//设置初始的采样比为1 即原始比例
int inSampleSize = 1;
//判断 当图片的宽度>高度时,就参照宽度采样;否则相反
if (outWidth>outHeight) {
inSampleSize = outWidth/mImg.getWidth();
} else {
inSampleSize = outHeight/mImg.getHeight();
}
//判断当采样比小于1时,按1计算 即图片宽高小于控件的宽高时,图片按原尺寸加载
if (inSampleSize<1) {
inSampleSize = 1;
}
return inSampleSize;
}
内容可能与标题与出入,原理仅供参考...