图片的三级缓存

图片的三级缓存是指网络缓存,本地缓存,以及内存缓存。

从获得数据的顺序上将,显示网络缓存得到数据,紧接着存入本地缓存,在使用是放入内存缓存。

分别介绍三个缓存方式:


1 网络缓存

网络缓存最重要的是使用AsyncTask自定义bitmapTask,

AsyncTask三个重要的函数:

doInBackground:后台耗时方法,子线程中进行

onPostExecute:doInBackground结束后,执行该方法,主线程中运行的

onProgressUpdate:更新进度,在主线程中进行调用

主要思想是后台异步下载,得到结果之后在主线程中进行更新。

package com.example.zhihuibj.utils.bitmap;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import com.lidroid.xutils.HttpUtils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;

/*
 * 网络缓存
 * 
 */
public class NetCacheUtils {

	
	/*
	 * 
	 */
	private MyLoaclCacheUtils mLocalCacheUtils;
	private MemoryCacheUtils mMemoryCacheUtils;
	public NetCacheUtils(MyLoaclCacheUtils LocalCacheUtils, MemoryCacheUtils MemoryCacheUtils) {
		mLocalCacheUtils=LocalCacheUtils;
		mMemoryCacheUtils=MemoryCacheUtils;
	}

	
	public void getBitmapFromNet(ImageView ivPic, String url) {
		new BitmapTask().execute(ivPic,url);// 传入的参数在doInBackground中获取,启动AsyncTask
		
	}
	/*
	 * 第一个参数:doInBackground 参数
	 * 第二个参数:onProgressUpdate 参数
	 * 第三个参数:onPostExecute 参数
	 */
	class BitmapTask extends AsyncTask<Object, Void, Bitmap>{

		private ImageView ivPic;
		private String url;

		/*
		 * 后台耗时方法,子线程中进行
		 * 
		 */
		@Override
		protected Bitmap doInBackground(Object... params) {
			 ivPic = (ImageView)params[0];
			 url = (String)params[1];
			 
			 ivPic.setTag(url);//确保图片是给定的URL,将URL与ImageView进行绑定
			 
			return DownLoadBitmap(url);
		}
		
		/*
		 * doInBackground结束后,执行该方法,主线程中运行的
		 */
		@Override
		protected void onPostExecute(Bitmap result) {
			if(result!=null)
			{
				String tagurl= (String) ivPic.getTag();
				
				
				if(url.equals(tagurl))//确保图片是给定的URL
				ivPic.setImageBitmap(result);
				mLocalCacheUtils.SetBitMapToLoacl(url, result);//写入本地缓存
				mMemoryCacheUtils.SetBitmaptoMemory(url, result);
				System.out.println("从网络获取图片....");
			}
			
		}
		
		/*
		 * 更新进度,在主线程中进行调用
		 */
		@Override
		protected void onProgressUpdate(Void... values) {
			// TODO Auto-generated method stub
			super.onProgressUpdate(values);
		}
	}
	
	/*
	 * 下载图片
	 */
	private Bitmap DownLoadBitmap(String url)
	{
		HttpURLConnection con = null;
		try {
			con = (HttpURLConnection)new URL(url).openConnection();
			con.setConnectTimeout(5000);
			con.setReadTimeout(5000);
			con.setRequestMethod("GET");
			con.connect();			
			
			int responseCode = con.getResponseCode();
			if(responseCode==200)
			{
				InputStream inputstream = con.getInputStream();
				Bitmap bitmap = BitmapFactory.decodeStream(inputstream);
				return bitmap;
			}
			
			
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{
			con.disconnect();
		}
		return null;
	}

}

2 本地缓存:

本地缓存主要是向sdcard中读写数据:

package com.example.zhihuibj.utils.bitmap;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.os.Environment;

public class MyLoaclCacheUtils {

	
	
	public static final String CACHE_PATH=Environment.getExternalStorageDirectory().getAbsolutePath()+"/zhihuibj_52";
	/**
	 * 从本地sdcard读图片
	 * @param url
	 */
	public Bitmap GetBitmapFromLoacl(String url){
		
		String fileName;
		try {
			fileName = MD5Encode.encode(url);
			File file = new File(CACHE_PATH,fileName);
			
			if(file.exists())
			{
				Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
				
				return bitmap;
			}
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
		
	}
	
	/**
	 * 向sdcard写图片
	 * @param url
	 * @param bitmap
	 */
	public void SetBitMapToLoacl(String url,Bitmap bitmap){
		try {
			String fileName= MD5Encode.encode(url);
			File file = new File(CACHE_PATH,fileName);
			
			
			File parentFile = file.getParentFile();
			if(!parentFile.exists()){//如果文件夹不存在,创建文件夹
				parentFile.mkdirs();
			}
			
			bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream(file));//将bitmap存到本地
			
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

MD5

本地缓存使用MD5对于文件名进行了转换:

package com.example.zhihuibj.utils.bitmap;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import android.os.Message;

public class MD5Encode {
	public static String encode(String string ) throws Exception
	{
		byte[] hash= MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
		StringBuilder hex = new StringBuilder(hash.length*2);
		
		for( byte b: hash)
		{
			if((b&0xFF)<0x10)
			{
				hex.append("0");
			}
			hex.append(Integer.toHexString(b&0xFF));
		}		
		
		return hex.toString();
		
	}

}



3 内存缓存:

内存缓存主要用到的是:LruCache,并复写了sizeof方法来得到每个图片的大小。

package com.example.zhihuibj.utils.bitmap;

import java.util.HashMap;

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

public class MemoryCacheUtils {
	
	//private HashMap<String,Bitmap> mMemoryCache =new HashMap<String ,Bitmap>();
	
	
	private LruCache<String,Bitmap> mMemoryCache;
	
	
	public MemoryCacheUtils(){
		int maxSize=(int) (Runtime.getRuntime().maxMemory()/8); //获取模拟器分配给APP的内存大小的八分之一
		mMemoryCache=new LruCache<String, Bitmap>(maxSize){

			@Override
			protected int sizeOf(String key, Bitmap value) {				
				return value.getHeight()*value.getWidth();			
			}
			
		};
	}
	
	/**
	 * 从内存中读取数据
	 * @param url
	 * @return 
	 */
	public Bitmap getBitmapFromMemory(String url)
	{		
		return mMemoryCache.get(url);		
	}
	
	/**
	 * 将数据写入内存
	 * @param url
	 * @param bitmap
	 */
	public void SetBitmaptoMemory(String url,Bitmap bitmap)
	{
		mMemoryCache.put(url, bitmap);	
	}
}


4 主调用方法:

package com.example.zhihuibj.utils.bitmap;

import android.app.Activity;
import android.graphics.Bitmap;
import android.widget.ImageView;

/*
 * 自定义图片加载工具
 */
public class MyBitMapUtils {

	
	
	
	private NetCacheUtils mNetCacheUtils;
	private MyLoaclCacheUtils mLocalCacheUtils;
	private MemoryCacheUtils mMemoryCacheUtils;
	

	public MyBitMapUtils(Activity mActivity)
	{		
		mLocalCacheUtils= new MyLoaclCacheUtils();
		mNetCacheUtils=new NetCacheUtils(mLocalCacheUtils,mMemoryCacheUtils);
		mMemoryCacheUtils=new MemoryCacheUtils();
	}
	
	public void display(ImageView ivPic,String url)
	{
		//从内存中读取
		
		
		Bitmap bitmap_memory = mMemoryCacheUtils.getBitmapFromMemory(url);
		
		if(bitmap_memory!=null)
		{
			ivPic.setImageBitmap(bitmap_memory);
			System.out.println("从内存读数据啦。。。。");	
			
			return;
			
		}
		
		
		//从SD卡中读取
		Bitmap bitmap = mLocalCacheUtils.GetBitmapFromLoacl(url);
		
		if(bitmap!=null)
		{
			ivPic.setImageBitmap(bitmap);
			System.out.println("从本地读数据啦。。。。");	
			mMemoryCacheUtils.SetBitmaptoMemory(url, bitmap);
			return;
		}
		
		
		//从网络中读取	
		mNetCacheUtils.getBitmapFromNet(ivPic, url);
	}
}



你可能感兴趣的:(android,项目)