图片的三级缓存是指网络缓存,本地缓存,以及内存缓存。
从获得数据的顺序上将,显示网络缓存得到数据,紧接着存入本地缓存,在使用是放入内存缓存。
分别介绍三个缓存方式:
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中图片的三级缓存机制,包括网络缓存、本地缓存(MD5)和内存缓存(LruCache)。首先,网络缓存通过AsyncTask实现异步加载并保存至本地;接着,本地缓存利用MD5进行数据存储;最后,内存缓存使用LruCache策略,确保高效加载。

1171

被折叠的 条评论
为什么被折叠?



