图片的三级缓存

/**
 * 自定义三级缓存工具类
 */
public class MyBitmapUtils {


private NetCacheUtils mNetCacheUtils;
private LocalCacheUtils mLocalCacheUtils;
private MemoryCacheUtils mMemoryCacheUtils;


public MyBitmapUtils() {
mMemoryCacheUtils = new MemoryCacheUtils();
mLocalCacheUtils = new LocalCacheUtils();
mNetCacheUtils = new NetCacheUtils(mLocalCacheUtils, mMemoryCacheUtils);


}


//加载图片进行展示
public void display(ImageView imageView, String url) {
//内存缓存: 速度很快, 不浪费流量, 优先
Bitmap bitmap = mMemoryCacheUtils.getMemroyCache(url);
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
System.out.println("从内存加载缓存啦!!!");
return;
}


//本地缓存: 速度快, 不浪费流量, 其次
bitmap = mLocalCacheUtils.getLocalCache(url);
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
System.out.println("从本地加载缓存啦!!!");
//写内存缓存
mMemoryCacheUtils.setMemoryCache(url, bitmap);
return;
}


//网络缓存: 速度慢, 浪费流量, 最后
mNetCacheUtils.getBitmapFromNet(imageView, url);
}


}


/**
 * 内存缓存
 * 
 * 因为从 Android 2.3 (API Level 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用和弱引用变得不再可靠。
 */
public class MemoryCacheUtils {

//private static HashMap<String,Bitmap> mHashMap = new HashMap<String,Bitmap>();


//private HashMap<String, SoftReference<Bitmap>> mHashMap = new HashMap<String, SoftReference<Bitmap>>();


private LruCache<String, Bitmap> mLruCache;


public MemoryCacheUtils() {
long maxMemory = Runtime.getRuntime().maxMemory();//获取虚拟机分配的最大内存,默认16MB
System.out.println("maxMemory:" + maxMemory);

//LRU: least recentlly used 最近最少使用算法
//A
//B
//C(最近最少使用)
//B
//A
//D


//maxSize:内存缓存上限
mLruCache = new LruCache<String, Bitmap>((int) (maxMemory / 8)) {


//返回单个对象占用内存的大小
@Override
protected int sizeOf(String key, Bitmap value) {
//int byteCount = value.getByteCount();
//  return getRowBytes() * getHeight();
//计算图片占用内存大小
int byteCount = value.getRowBytes() * value.getHeight();
return byteCount;
}
};
}


//写缓存
public void setMemoryCache(String url, Bitmap bitmap) {
// SoftReference<Bitmap> soft = new SoftReference<Bitmap>(bitmap);//用软引用包装bitmap
// mHashMap.put(url, soft);
mLruCache.put(url, bitmap);
}


//读缓存
public Bitmap getMemroyCache(String url) {
// SoftReference<Bitmap> soft = mHashMap.get(url);
// if (soft != null) {
// Bitmap bitmap = soft.get();//从软引用中取出当前对象
// return bitmap;
// }
//
// return null;
//return mHashMap.get(url);
return mLruCache.get(url);
}


}


/**
 * 本地缓存
 */
public class LocalCacheUtils {


String PATH = Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/zhbj_cache/";//缓存文件夹


//写缓存
public void setLocalCache(String url, Bitmap bitmap) {
//将图片保存在本地文件
File dir = new File(PATH);
if (!dir.exists() || !dir.isDirectory()) {
dir.mkdirs();//创建文件夹
}


try {
File cacheFile = new File(dir, MD5Encoder.encode(url));//创建本地文件, 以url的md5命名
//将图片压缩保存在本地; 参1:图片格式, 参2:压缩比(0-100),100表示不压缩; 参3:输出流
bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream(
cacheFile));
} catch (Exception e) {
e.printStackTrace();
}
}


//读缓存
public Bitmap getLocalCache(String url) {
try {
File cacheFile = new File(PATH, MD5Encoder.encode(url));


if (cacheFile.exists()) {
//缓存存在
Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(
cacheFile));
return bitmap;
}


} catch (Exception e) {
e.printStackTrace();
}


return null;
}
}


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


private LocalCacheUtils localCacheUtils;
private MemoryCacheUtils memoryCacheUtils;


public NetCacheUtils(LocalCacheUtils localCacheUtils,
MemoryCacheUtils memoryCacheUtils) {
this.localCacheUtils = localCacheUtils;
this.memoryCacheUtils = memoryCacheUtils;
}


public void getBitmapFromNet(ImageView imageView, String url) {
//异步下载图片
new BitmapTask().execute(imageView, url);


}


class BitmapTask extends AsyncTask<Object, Void, Bitmap> {


private ImageView imageView;
private String url;


@Override
protected void onPreExecute() {
super.onPreExecute();
}


@Override
protected Bitmap doInBackground(Object... params) {
imageView = (ImageView) params[0];
url = (String) params[1];


imageView.setTag(url);//给当前ImageView打标签


//使用url下载图片
Bitmap bitmap = download(url);


return bitmap;
}


@Override
protected void onPostExecute(Bitmap result) {
if (result != null) {
//给ImageView设置图片
//由于ListView的重用机制,导致某个item有可能展示它所重用的那个item的图片, 导致图片错乱
//解决方案:确保当前设置的图片和当前显示的imageview完全匹配
String url = (String) imageView.getTag();//获取和当前ImageView绑定个url
if (this.url.equals(url)) {//判断当前下载的图片的url是否和imageView的url一致, 如果一致,说明图片正确
imageView.setImageBitmap(result);
System.out.println("从网络下载图片啦!!!");


//写本地缓存
localCacheUtils.setLocalCache(url, result);
//写内存缓存
memoryCacheUtils.setMemoryCache(url, result);
}
}
}


}


//使用url下载图片
public Bitmap download(String url) {
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(6000);
conn.setReadTimeout(6000);


conn.connect();


int responseCode = conn.getResponseCode();
if (responseCode == 200) {
InputStream in = conn.getInputStream();
//使用输入流生成Bitmap对象
Bitmap bitmap = BitmapFactory.decodeStream(in);
return bitmap;
}


} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}
}


return null;
}


}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值