Android实际开发中,在加载大量图片的时候,比如ViewPager、GridView、ListView中,加载了大量的比较大图片就容易出现OOM(内存溢出)的异常,这是因为一个应用的最大内存使用只有16M,超过了这个值,就会出现OOM。所以我们实际开发中,要想避免OOM出现就要对相应的图片进行压缩处理。

本文即使用了BitmapFactory和BitmapFactory.Option这两个类,对图片进行相应的尺寸压缩处理。经测试,成功解决了未压缩图片之前出现的OOM异常。

实现效果图:

本Demo使用的图片大小为2M左右(压缩以前)。

我压缩图片之前:

我这里将压缩的代码注释掉了:


运行结果:


进行压缩处理后的图片:

压缩后图片大小为:


大约为98KB


运行结果:


源代码:


布局文件:

activity_main:

        

list_item.xml:

<?xml version="1.0" encoding="utf-8"?>        


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 };@Overrideprotected 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;}@Overridepublic int getCount() {return items.length;}@Overridepublic Object getItem(int position) {return items[position];}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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;}}

BitmapCompressTools(压缩工具类):

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 inSampleSizeoptions.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;}}

达到了预期效果,但是写到这里滑动ListView的时候,还是会有些卡顿,有这方面解决经验的可以给我留言讨论。

源代码已上传到资源中,可到我的资源中下载。


更多相关文章

  1. Android学习笔记之ImageSwitcher
  2. 项目在android studio 中出现 .9.png问题的解决方案
  3. Android(安卓)富文本编辑器 图文混排
  4. Android(安卓)减小安装包的大小、apk瘦身
  5. 迷途d书童 Android(安卓)如何从系统图库中选择图片
  6. Android开发心得——网页通过webview调用Android的图片或文件选
  7. ImageView中图片保存到文件
  8. mipmap和drawable的区别
  9. Android(安卓)res下三个drawable文件夹的用途

随机推荐

  1. Android跨进程通信传输大数据
  2. android activity onSearchRequested()
  3. API Demos 2.2 研读笔记(5)——Window Feat
  4. Android动画之 Alpha与Translate结合使用
  5. 2011.09.07(5)——— android 跨进程通信之
  6. Android ProgressDialog的两种用法
  7. Android屏幕尺寸适配注意事项
  8. Tegra Android Development Pack | NVIDI
  9. android 访问SD卡
  10. Android一个大众化的设置界面