概述
public linkedhashmap(int initialcapacity, float loadfactor, boolean accessorder) {
super(initialcapacity, loadfactor);
init();
this.accessorder = accessorder;
}
所以在lrucache中应该选择accessorder = true,当我们调用put、get方法时,linkedhashmap内部会将这个item移动到链表的尾部,即在链表尾部是最近刚刚使用的item,链表头部就是最近最少使用的item。当缓存空间不足时,可以remove头部结点释放缓存空间。
下面举例lrucache的典型使用姿势:
int maxmemory = (int) (runtime.getruntime().maxmemory() / 1024);
int cachesize = maxmemory / 8;
mmemorycache = new lrucache(cachesize) {
@override
protected int sizeof(string key, bitmap bitmap) {
return bitmap.getrowbytes() * bitmap.getheight() / 1024;
}
};
// 向 lrucache 中添加一个缓存对象
private Android开源项目《ali1024.coding.net/public/P7/Android/git》 void addbitmaptomemorycache(string key, bitmap bitmap) {
if (getbitmapfrommemcache(key) == null) {
mmemorycache.put(key, bitmap);
}
}
//获取一个缓存对象
private bitmap getbitmapfrommemcache(string key) {
return mmemorycache.get(key);
}
上述示例代码中,总容量的大小是当前进程的可用内存的八分之一(官方推荐是八分之一哈,你们可以自己视情况定),sizeof()方法计算了bitmap的大小,sizeof方法默认返回的是你缓存item数目,源码中直接return 1(这里的源码比较简单,可以自己看看~)。
如果你需要cache中某个值释放,可以重写entryremoved()方法,这个方法会在元素被put或者remove的时候调用,源码默认是空实现。重写entryremoved()方法还可以实现二级内存缓存,进一步提高性能。思路如下:重写entryremoved(),把删除掉的item,再次存入另一个linkedhashmap中。这个数据结构当做二级缓存,每次获得图片的时候,按照一级缓存 、二级缓存、sdcard、网络的顺序查找,找到就停止。
###2.disklrucache
当我们需要存大量图片的时候,我们指定的缓存空间可能很快就用完了,lrucache会频繁地进行trimtosize操作将最近最少使用的数据remove掉,但是hold不住过会又要用这个数据,又从网络download一遍,为此有了disklrucache,它可以保存这些已经下载过的图片。当然,从磁盘读取图片的时候要比内存慢得多,并且应该在非ui线程中载入磁盘图片。disklrucache顾名思义,实现存储设备缓存,即磁盘缓存,它通过将缓存对象写入文件系统从而实现缓存效果。
ps: 如果缓存的图片经常被使用,可以考虑使用contentprovider。
disklrucache的实现原理:
lrucache采用的是linkedhashmap这种数据结构来保存缓存中的对象,那么对于disklrucache呢?由于数据是缓存在本地文件中,相当于是持久保存的一个文件,即使app kill掉,这些文件还在滴。so , 到底是啥?disklrucache也是采用linekedhashmap这种数据结构,但是不够,需要加持buff
日志文件。日志文件可以看做是一块“内存”,map中的value只保存文件的简要信息,对缓存文件的所有操作都会记录在日志文件中。
disklrucache的初始化:
下面是disklrucache的创建过程:
private static final long disk_cache_size = 1024 * 1024 * 50; //50mb
file diskcachedir = getdiskcachedir(mcontext, “bitmap”);
if (!diskcachedir.exists()) {
diskcachedir.mkdirs();
}
if (getusablespace(diskcachedir) > disk_cache_size) {
try {
mdisklrucache = disklrucache.open(diskcachedir, 1, 1,
disk_cache_size);
} catch (ioexception e) {
e.printstacktrace();
}
}
瞅了一眼,可以知道重点在open()函数,其中第一个参数表示文件的存储路径,缓存路径可以是sd卡上的缓存目录,具体是指/sdcard/android/data/package_name/cache,package_name表示当前应用的包名,当应用被卸载后, 此目录会一并删除掉。如果你希望应用卸载后,这些缓存文件不被删除,可以指定sd卡上其他目录。第二个参数表示应用的版本号,一般设为1即可。第三个参数表示单个结点所对应数据的个数,一般设为1。第四个参数表示缓存的总大小,比如50mb,当缓存大小超过这个设定值后,disklrucache会清除一些缓存保证总大小不会超过设定值
disklrucache的数据缓存与获取缓存:
数据缓存操作是借助disklrucache.editor类完成的,editor表示一个缓存对象的编辑对象。
new thread(new runnable() {
最后
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021BAT 面试真题解析,我把大厂面试中常被问到的技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。
还有 高级架构技术进阶脑图 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
Android 基础知识点
Java 基础知识点
Android 源码相关分析
常见的一些原理性问题
希望大家在今年一切顺利,进到自己想进的公司,共勉!
a 基础知识点**
Android 源码相关分析
常见的一些原理性问题
[外链图片转存中…(img-8T2ndP5m-1650169564583)]
希望大家在今年一切顺利,进到自己想进的公司,共勉!
最后
以上就是伶俐银耳汤为你收集整理的android-bitmap的缓存策略的全部内容,希望文章能够帮你解决android-bitmap的缓存策略所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复