Android实际开发中,在加载大量图片的时候,比如ViewPager、GridView、ListView中,加载了大量的比较大图片就容易出现OOM(内存溢出)的异常,这是因为一个应用的最大内存使用只有16M,超过了这个值,就会出现OOM。所以我们实际开发中,要想避免OOM出现就要对相应的图片进行压缩处理。
本文即使用了BitmapFactory和BitmapFactory.Option这两个类,对图片进行相应的尺寸压缩处理。经测试,成功解决了未压缩图片之前出现的OOM异常。
实现效果图:
本Demo使用的图片大小为2M左右(压缩以前)。
我压缩图片之前:
我这里将压缩的代码注释掉了:
运行结果:
进行压缩处理后的图片:
压缩后图片大小为:
大约为98KB
运行结果:
源代码:
布局文件:
activity_main:
MainActivity:
package com.android_bitmapcompressdemo;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
public class MainActivity extends Activity {
private ListView listView;
private MyAdapter adapter;
private int[] items = new int[] { R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
adapter = new MyAdapter(this, items);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
ListView适配器:MyAdapter:
package com.android_bitmapcompressdemo;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class MyAdapter extends BaseAdapter {
private int[] items = new int[] {};
private Context context;
private String TAG = "zhongyao";
private Bitmap bitmap = null;
public MyAdapter(Context context, int[] items) {
this.context = context;
this.items = items;
}
@Override
public int getCount() {
return items.length;
}
@Override
public Object getItem(int position) {
return items[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.imageView = (ImageView) convertView.findViewById(R.id.imageView);
holder.textView = (TextView) convertView.findViewById(R.id.textView);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
bitmap = BitmapCompressTools.decodeSampledBitmapFromResource(
context.getResources(), R.drawable.pc, 100, 100);
Log.d(TAG, "压缩之后的图片大小为:" + bitmap.getByteCount());
holder.imageView.setImageBitmap(bitmap);
holder.textView.setText("图片"+position);
return convertView;
}
class ViewHolder {
ImageView imageView;
TextView textView;
}
}
package com.android_bitmapcompressdemo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class BitmapCompressTools {
public static Bitmap decodeSampledBitmapFromResource(Resources res,
int resId, int reqWidth, int reqHeight) {
// 给定的BitmapFactory设置解码的参数
final BitmapFactory.Options options = new BitmapFactory.Options();
// 从解码器中获取原始图片的宽高,这样避免了直接申请内存空间
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// 压缩完后便可以将inJustDecodeBounds设置为false了。
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
/**
* 指定图片的缩放比例
*
* @param options
* @param reqWidth
* @param reqHeight
* @return
*/
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 halfHeight = height / 2;
// // final int halfWidth = width / 2;
// // while ((halfHeight / inSampleSize) > reqHeight
// // && (halfWidth / inSampleSize) > reqWidth) {
// // inSampleSize *= 2;
// // }
//
/**
* 压缩方式一
*/
// 计算压缩的比例:分为宽高比例
final int heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
// }
return inSampleSize;
}
}
源代码已上传到资源中,可到我的资源中下载。