高效展示图片LruCache

在android中展示图片过多就会出现内存溢出,为了能够高效的展示出图片这里就用缓存来处理。

首先我们写个缓存管理类ImageManager

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.support.v4.util.LruCache;
import android.util.Log;
import android.widget.ImageView;

import com.weather.forecast.R;
//缓存管理类
public class ImageManager {
	private Context context;
	private LruCache<String, Bitmap> mMemoryCache;
	private static ImageManager instance;
	private Executor mExecutor;

	private ImageManager() {
	}
	//单例
	public static ImageManager getInstance() {
		if (instance == null) {
			instance = new ImageManager();
		}
		return instance;
	}
	//应用程序初始化时调用
	public void init(Context context) {
		this.context = context;
		// 获取应用程序最大可用内存
		int maxMemory = (int) Runtime.getRuntime().maxMemory();
		// 设置图片缓存大小为程序最大可用内存的1/8
		int cacheSize = maxMemory / 8;
		mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
			@Override
			protected int sizeOf(String key, Bitmap bitmap) {
				return bitmap.getByteCount();
			}
		};

		mExecutor = Executors.newFixedThreadPool(3);
	}
	/**
	 * 
	 * @param url 传入路径
	 * @param image 图片控件
	 * @param Height 图片压缩的高
	 * @param Width 图片压缩的宽
	 * @param type 用来判断是本地照片还是资源文件中的图片(1是资源文件中的图片、2是本地图片)
	 */
	public void loadImage(String url, ImageView image,int Height, int Width, int type) {
		image.setTag(url);
		Bitmap bm = mMemoryCache.get(url);
		if (bm != null) {
			image.setImageBitmap(bm);
		} else {
			//默认图
			image.setImageResource(R.drawable.default_image);
			//异步下载图片
			BitmapWorkerTask task = new BitmapWorkerTask(image);
			task.executeOnExecutor(mExecutor, url, Height, Width, type);
		}
	}

	/**
	 * 异步下载图片的任务。
	 * 
	 * @author guolin
	 */
	class BitmapWorkerTask extends AsyncTask<Object, Void, Bitmap> {

		/**
		 * 图片的URL地址
		 */
		private String imageUrl;
		private ImageView image;

		public BitmapWorkerTask(ImageView image) {
			super();
			this.image = image;
		}

		@SuppressWarnings("unused")
		@Override
		protected Bitmap doInBackground(Object... params) {
			Bitmap bm = null;
			imageUrl = (String) params[0];
			Log.i("jjf", "imageUrl:" + imageUrl);
			int mHeight = (Integer) params[1];
			int mWidth = (Integer) params[2];
			int mType = (Integer) params[3];
			if (mType == 1) {
				//对资源图片进行压缩获得bitmap
				bm = DateUtil.BitmapResource(context, imageUrl, mWidth, mHeight);
			}else{
				//对本地图片进行压缩获得bitmap
				bm = DateUtil.getBitmapPath(imageUrl, mWidth, mHeight);
			}
			if (bm != null) {
				//进行存储(键值对形式)
				mMemoryCache.put(imageUrl, bm);
			}
			return bm;
		}

		@Override
		protected void onPostExecute(Bitmap bitmap) {
			super.onPostExecute(bitmap);
			// 根据Tag找到相应的ImageView控件,将下载好的图片显示出来。
			if (bitmap != null && imageUrl != null && image != null
					&& image.getTag().equals(imageUrl)) {
				image.setImageBitmap(bitmap);
			}
		}
	}

}

程序初始化是调用如下:

public class GAPP extends Application {
	@Override
	public void onCreate() {
		ImageManager.getInstance().init(getApplicationContext());
	}

}

清单文件中注册

<application
        android:name="yong.desk.weather.GAPP"
        android:icon="@drawable/icon"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.Holo.Light.NoActionBar" >
        <activity

图片压缩类DateUtil

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class DateUtil {

	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 ? widthRatio : heightRatio;
			if (heightRatio == widthRatio) {
				inSampleSize = widthRatio;
			}
		}
		return inSampleSize;
	}

	// 资源文件的压缩
	public static Bitmap BitmapResource(Context context, String str,
			int reqWidth, int reqHeight) {
		// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
		int resId = Integer.parseInt(str);
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeResource(context.getResources(), resId, options);
		// 调用上面定义的方法计算inSampleSize值
		options.inSampleSize = calculateInSampleSize(options, reqWidth,
				reqHeight);
		// 使用获取到的inSampleSize值再次解析图片
		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeResource(context.getResources(), resId,
				options);
	}

	// 本地文件的压缩
	public static Bitmap getBitmapPath(String str, int Width, int Height) {
		Bitmap mbitMap = null;
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		options.inDither = false;
		options.inPreferredConfig = Bitmap.Config.RGB_565;
		BitmapFactory.decodeFile(str, options);
		options.inSampleSize = calculateInSampleSize(options, Width, Height);
		options.inJustDecodeBounds = false;
		mbitMap = BitmapFactory.decodeFile(str, options);
		return mbitMap;
	}

}

工具类都已经完成了,现在就在我们要使用的地方调用方法就ok了,下面是在gridview的适配器中调用。其他地方也是同样的使用

@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder = null;
		if (convertView == null) {
			holder = new ViewHolder();
			convertView = inflater.inflate(
					R.layout.gridview_list_background_item, null);
			holder.imageName = (TextView) convertView
					.findViewById(R.id.gridview_lsit_item_textView);
			holder.image = (ImageView) convertView
					.findViewById(R.id.gridview_lsit_item_imageView);
			LayoutParams para = holder.image.getLayoutParams();
			para.height = Height;
			para.width = Width;
			holder.image.setLayoutParams(para);
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}
		//判断本地文件路径是否为空
		if (!getImagePath(position).equals("")) {
			//判断本地文件是否存在
			if (FileUtil.isExist(getImagePath(position))) {
				//调用方法显示本地图片
				ImageManager.getInstance().loadImage(
						getImagePath(position), holder.image, Height, Width, 2);

			} else {
				//调用方法显示资源文件中的图
				ImageManager.getInstance().loadImage(
						Integer.toString(mImages[position]), holder.image, Height, Width, 1);
			}
		} else {
			//调用方法显示资源文件中的图
			ImageManager.getInstance().loadImage(
					Integer.toString(mImages[position]), holder.image, Height, Width, 1);
		}
		holder.imageName.setText(list[position]);
		return convertView;
	}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值