- 三级缓存
- Lrucache
- File
三级缓存,第一级是内存缓存,第二级是文件缓存,第三级是网络缓存。
针对于图片的一个缓冲机制
LruCache 详解
LruCache 选择的数据结构是 LinkedHashMap,一个 util 包中的双向循环链表。
每当我们更新(即调用 put 方法)或访问(即调用 get 方法)map 中的结点时,LinkedHashMap 内部都会将这个结点移动到链表的尾部,
因此,在链表的尾部是最近刚刚使用的结点,所以当我们的缓存空间不足时,就应该持续把链表头部结点移除掉,直到有剩余空间放置新结点。
- 初始化 Lrucache 对象
通过获取到程序可用的内存,适当的控制缓存的大小。
实际中,通常通过重写 Application 类的方法来实现全局范围内获取该变量。
final int cachesize = (ActivityManager)getSystemService(
Context.ACTIVITY_SERVICE)).getMemoryClass();
LruCache myLruCache = new LruCache<String,Bitmap>(cachesize){
protected int sizeOf(String key,Bitmap bitmap){
return bitmap.getByteCount()/1024;
}
}
-
添加缓存操作
添加语句Put:myLruCache.put(string,bitmap)
通常会先判断文件是否已经在缓存中存在,
如果存在,会 覆盖原来的数据,并返回旧的数据。 -
在缓存中读取文件
读取语句:myLruCache.get(string);
/**
* @description 将bitmap添加到内存中去
*
* @param key
* @param bitmap
*/
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
mMemoryCache.put(key, bitmap);
}
}
/**
* @description 通过key来从内存缓存中获得bitmap对象
*
* @param key
* @return
*/
private Bitmap getBitmapFromMemCache(String key) {
return mMemoryCache.get(key);
}
-
节点被删除时的回调方法
entryRemoved() 是一个可以被重写的空方法,
protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue)
在节点数据被移除的时候被调用
包括手动 remove、put 操作中被覆盖、到达缓存上限被移除,都可以通过这个方法进行资源的回收等操作
-
根据 maxSize 清理缓存
trimToSize 在每次 put 操作都会执行一次,这时候的 maxSize 等于我们在初始化 LruCache 时传入的数值
public void trimToSize(int maxSize)
但我们也可以手动调用这个方法设置一个临时的 maxSize 来清理缓存
-
对重写 sizeOf() 的说明:
初始化 LruCache 的时候需要重写 sizeOf(),因为 LruCache 允许存入不同类型的对象,而对象的类型不同,测量大小的方法也是不一样的。
bitmap.getByteCount();
bitmap.getRowBytes() * bitmap.getHeight(); //兼容低版本
string.length();
stringList.length;
但也有这种:
return bitmap.getByteCount() / 1024;//返回了图片的数量
这种情况,见过几次不推荐
File
LruCache 将图片保存在缓存中,适合不需要保存太久或者实时更新的文件和数据。
File 是java中 io 下的一个类,在系统中创建一个文件来保存数据。
/**
* 二建缓存,读取bitmap的操作
* @param path
* @return
*/
private Bitmap fromSecondCaush(String path){
String fileName=path.substring(path.lastIndexOf("/")+1);
String filePath=context.getExternalFilesDir(null)+"/"+fileName;
File file=new File(filePath);
if(file.exists()){
return BitmapFactory.decodeFile(file.getAbsolutePath());
}
return null;
}
/**
* 二级缓存,保存的操作
* @param path
* @throws IOException
*/
private Bitmap putSecondCaush(String path,Bitmap bitmap) throws IOException {
String fileName=path.substring(path.lastIndexOf("/")+1);
String filePath=context.getExternalFilesDir(null)+"/"+fileName;
FileOutputStream fos = new FileOutputStream(filePath);
//将 bitmap 质量压缩至 path
bitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);
fos.close();
return bitmap;
}
context.getExternalFilesDir();
获取到 SDCard/Android/data/"应用包名"/files/目录,一般在该目录下放一些长时间保存的数据。
context.getExternalCacheDir();
获取到 SDCard/Android/data/"应用包名"/cache/目录,一般在该目录下放一些临时的缓存数据。
所以fileName就是保存的文件名,filePath是文件保存的目录。
网友评论