获取图片资源用到的三级缓存技术

/**
  
 三级缓存的操作:
是否在内存中   会把图片放置在一个集合里面  
 从硬盘中获取:sdcard
 从网络加载







import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.os.AsyncTask;
import android.support.v4.util.LruCache;
import android.util.DisplayMetrics;
import android.widget.ImageView;


 *AsyncTask   :主要是封装了线程池  + Handler  
 *如果使用AsyncTask  去除线程池   Handler
 */
public class BitmapUtils {

	private File dir;//存放图片的目录
	//android在4.0添加的一个缓存支持类
	int maxSize = (int) (Runtime.getRuntime().maxMemory()/8);
	private LruCache<String, Bitmap> cache = new LruCache<String, Bitmap>(maxSize){
		//返回图片的数据
		@Override
		protected int sizeOf(String key, Bitmap value) {
			return value.getRowBytes()*value.getHeight()/1024;
		}
	};//指定缓存的大小
	//LruCache 自身有一套算法:移除里面使用频率低的对象
	private Context context;
	public BitmapUtils(Context context) {
		this.context = context;
		dir = new File("/mnt/sdcard/bitmapcache");
		if(!dir.exists()){
			dir.mkdirs();//创建目录
		}
	}
	/**
	 * 显示图片
	 * @param iv
	 * @param url
	 */
	public void display(ImageView iv,String url){
		Bitmap bitmap = null;//图片
		//1从内存中获取
		bitmap = fromCacheGetBitmap(url);
		if(bitmap != null){
			iv.setImageBitmap(bitmap);
			return;
		}
		//2 从sdcard获取
		bitmap = fromSdcardGetBitmap(url);
		if(bitmap != null){
			iv.setImageBitmap(bitmap);
			return;
		}
		//3 从网络上获取图片
		fromInternetGetBitmap(iv,url);
	}
	/**
	 * 从内存中获取图片:使用一个map集合来存储图片  oom异常  16M内存空间
	 * java里面有一个对象引用的机制
	 * 1 强引用:  Object obj = new Object();  只要在使用就不可能被垃圾回收器回收
	 * 2 不是强引用
	 *   2.1 软引用  :只保证该软件能够正常运行  
	 *   2.2 弱引用 :当发现内存不足  马上就回收
	 *   2.3 虚引用  :只要回收器一运行马上回收
	 * @param url
	 * @return
	 */
	private Bitmap fromCacheGetBitmap(String url){
		Bitmap bitmap = null;
		bitmap = cache.get(url);
		return bitmap;
	}

	/**
	 * 从sdcard里面获取图片
	 * @param url
	 * @return
	 */
	private Bitmap fromSdcardGetBitmap(String url){
		Bitmap bitmap = null;
		File file = new File(dir,getFileName(url));
		bitmap = decodeFile(file);
		if(bitmap != null){
			//把图片存入内存集合
			cache.put(url, bitmap);
		}
		return bitmap;
	}
	/**
	 * 从网络获取图片
	 * @param url
	 */
	private void fromInternetGetBitmap(ImageView iv,String url){
		//AsyncTask   执行异步任务   每次都需要new
		new MyAsyncTask().execute(new ImageViewURl(iv,url));
	}
	private class MyAsyncTask extends AsyncTask<ImageViewURl, Integer, ImageViewBitmap>{
		//下载前调用
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}
		//下载
		@Override
		protected ImageViewBitmap doInBackground(ImageViewURl... params) {
			try {
				String url = params[0].url;
				ImageView iv = params[0].iv;
				HttpClient client = new DefaultHttpClient();
				client.getParams().setParameter(HttpConnectionParams.CONNECTION_TIMEOUT, 3000);
				HttpGet request = new HttpGet(url);
				HttpResponse response = client.execute(request);
				if(response.getStatusLine().getStatusCode() == 200){
					InputStream inputStream = response.getEntity().getContent();
					//把流处理成图片
					Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
					//1 把bitmap放入集合
					cache.put(url, bitmap);
					//2 把bitmap放置在sdcard
					File file = new File(dir,getFileName(url));
					FileOutputStream stream = new FileOutputStream(file);
					bitmap.compress(CompressFormat.JPEG, 100, stream);
					return new ImageViewBitmap(iv, bitmap);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}
		//下载完成
		@Override
		protected void onPostExecute(ImageViewBitmap result) {
			super.onPostExecute(result);
			result.iv.setImageBitmap(result.bitmap);
		}
	}
	/**
	 * 使用AsyncTask去加载网络图片
	 * @author apple
	 *
	 */
	static class ImageViewURl{
		ImageView iv;
		String url;
		public ImageViewURl(ImageView iv, String url) {
			super();
			this.iv = iv;
			this.url = url;
		}
	}
	/**
	 * 网络加载完成后的对象
	 * @author apple
	 *
	 */
	static class ImageViewBitmap{
		ImageView iv;
		Bitmap bitmap;
		public ImageViewBitmap(ImageView iv, Bitmap bitmap) {
			super();
			this.iv = iv;
			this.bitmap = bitmap;
		}
	}

	/**
	 * 获取图片的名称
	 * @param url
	 * @return
	 */
	private String getFileName(String url){
		return Md5Utils.encode(url);
	}
	/**
	 * OOM大图片处理
	 * @param file
	 * @return
	 */
	public Bitmap decodeFile(File file){
		Options opts = new Options();
		opts.inJustDecodeBounds = true;//只加载图片的宽度
		opts.inPurgeable = true;//加载图片的像素点是可以清除
		opts.inInputShareable = true;
		BitmapFactory.decodeFile(file.getAbsolutePath(), opts);//此次加载就是为获取图片的宽高
		opts.inSampleSize = calculatorSampleSize(opts);//设置缩放的比率
		opts.inJustDecodeBounds = false;//加载整个图片的内容
		return BitmapFactory.decodeFile(file.getAbsolutePath(), opts);
	}
	/*
	 * 计算缩放比率
	 */
	private int calculatorSampleSize(Options opts) {
		int inSamleSize = 1;
		int outWidth = opts.outWidth;
		int outHeight = opts.outHeight;
		//获取手机屏幕的宽高
		DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
		int widthPixels = displayMetrics.widthPixels;
		int heightPixels = displayMetrics.heightPixels;
		//只有加载的图片大于屏幕的宽高
		if(outWidth > widthPixels || outHeight > heightPixels){
			int scaleX = outWidth/widthPixels;
			int scaleY = outHeight/heightPixels;
			inSamleSize = scaleX > scaleY?scaleX:scaleY;
		}
		return inSamleSize;
}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值