最近在项目中需要做到海报动态分类,为了防止多图出现OOM的情况,采用了比较主流的LruCache技术。
该技术主要是使用LruCache和DiskLruCache实现双缓存的,LruCache使用运行内存进行存储,DiskLruCache使用的是缓存(cache),当内存存储达到设定的比例后,就会采取DiskLruCache。
下面简单介绍这2个的使用方法。
1、LruCache
(1)初始化LruCache
LruCache<String, Bitmap> mMemCache mMemCache = new LruCache<String, Bitmap>(MEMORYCACHE_MAXSIZE) {
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();
}
};
其中MEMORYCACHE_MAXSIZE = (int) (Runtime.getRuntime().maxMemory() / 8);(将程序内存1/8作为内存缓存)
(2)将Bitmap 对象存入内存缓存中
public void putInMem(String urlStr, Bitmap bitmap) {
Log.w(tag, "putInMem");
if (mMemCache.get(urlStr) == null) {
mMemCache.put(urlStr, bitmap);
}
}
(3)通过URL字符串从内存中查找
public Bitmap getFromMemCache(String urlStr) {
Log.w(tag, "getFomMem");
Bitmap bitmap = mMemCache.get(urlStr);
if (bitmap != null) {
return bitmap;
} else return null;
}
(4)清除LruCache
mMemCache.remove(String key);
2、DiskLruCache
(1)初始化
DiskLruCache mDiskCache = DiskLruCache.open(getCacheDir(dirName), version, 1, DISKORYCACHE_MAXSIZE);
(其中getCacheDir为获取缓存路径)
(2)将Url对应的Bitmap对象存入缓存中
public void putInDisk(String urlStr, Bitmap bitmap) {
Log.w(tag, "putInDisk"); // 存入 内存缓存
try {
long tick = System.currentTimeMillis();
String key = hashKeyForDisk(urlStr);
DiskLruCache.Editor editor = mDiskCache.edit(key);
if (editor != null) {
OutputStream os = editor.newOutputStream(0);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
InputStream in = new ByteArrayInputStream(baos.toByteArray());
int len;
byte[] buffer = new byte[2048];
while ((len = in.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
os.close();
in.close();
editor.commit();
long tock = System.currentTimeMillis();
Log.w(tag, "time " + (tock - tick));
}
} catch (Exception e) {
e.printStackTrace();
}
}
(3)从外存(SD)根据URL 字符串查找
public Bitmap getFromDiskCache(String urlStr) {
Log.w(tag, "getFromDisk"); // 从内存读取,首先读取到的事快照
Bitmap bitmap = null;
try {
String key = hashKeyForDisk(urlStr);
DiskLruCache.Snapshot snapShot = mDiskCache.get(key);
if (snapShot == null) {
return null;
}
// 从外存读取,并存入内存缓存
snapShot = mDiskCache.get(key);
InputStream is = snapShot.getInputStream(0);
bitmap = BitmapFactory.decodeStream(is);
if (bitmap != null) {
Log.w(tag, "Disk Fikd OK");
}
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
需要注意的是DiskLruCache存入缓存或者读取缓存时需要根据Url字符串生成的MD5值去取
//将URL字符串编码MD5
private static String hashKeyForDisk(String urlStr) {
Log.w(tag, "hashKeyForDisk");
String cacheStr;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(urlStr.getBytes());
switch (cacheStr = bytesToHexString(md.digest())) {
}
} catch (NoSuchAlgorithmException e) {
cacheStr = String.valueOf(urlStr.hashCode());
e.printStackTrace();
}
return cacheStr;
}
(4)清除
mDiskCache.remove(key);
(其中key是根据Url字符串生成的MD5值)
也可以使用mDiskCache.delete();