Android中的LruCache的原理和使用
Android中的LruCache的原理和使用
LruCache,虽然很多文章都把LRU翻译成“最近最少使用”缓存策略,但Android中的LruCache真的如此吗?
答案是No,它只做到了控制“最近使用”!
原理
数据结构
LruCache采用LinkedHashMap作为存储的数据结构,那么为什么是LinkedHashMap?
LinkedHashMap特性简介
- LinkedHashMap基于HashMap,具有HashMap高效查找、自动扩容等特性
- 在HashMap基础上,增加了一个双向链表存储K-V对、实现了自己的遍历器LinkedHashIterator,默认情况下可以做到根据数据插入顺序有序地遍历
- 提供重载构造方法供外部控制accessOrder,以实现根据访问顺序有序地遍历
初始化
public LruCache(int maxSize) {
if (maxSize <= 0) {
throw new IllegalArgumentException("maxSize <= 0");
}
this.maxSize = maxSize;
this.map = new LinkedHashMap<K, V>(0, 0.75f, true);
}
LruCache的构造方法如上,可见LruCache初始化时就使用了上面提到的LinkedHashMap的第三点特性,即在数据结构层面实现了“最近使用”。
存储
当调用put方法添加/设置存储内容时,LruCache依次做了这么几件事:
- 判空,即不允许key/value为null
- 总容量size增加上计算传入的K-V大小
- 将传入的K-V存入LinkedHashMap
- 如过LinkedHashMap中已存在相同K,总容量size减去替换掉的K-VOld大小
- 通知VOld被替换(子类实现entryRemoved以监听)
- 比较总容量size和最大容量maxSize,若大于maxSize则循环移除LinkedHashMap头结点(即最久未被访问的结点)直至size小于等于maxSize
获取
当调用get方法获取存储内容时,LruCache依次做了这些事:
- 判空
- 从LinkedHashMap中取出与K对应的V值并返回。如果子类未实现create方法以达到当缓存未命中时创建并存入新V的话,返回null,get流程结束。
- 通过create创建VNew,并尝试把VNew存储到LinkedHashMap中,流程类似存储过程,不同之处在于当K冲突时,会舍弃掉新创建的VNew。不要奇怪为什么明明上面通过K取V的时候没取到,这里却会K冲突,因为LruCache为了性能考虑(防止子类自定义的create方法耗时过长影响get方法执行性能),只对从LinkedHashMap中取值的过程做了同步处理,这样在多线程的情况下就可能出现A线程在create的时候,B线程已经将K-VB存入了map。
- 返回上面创建的VNew或者VB
使用
用LruCache实现一个简单的图片缓存
class LruImageCache extends LruCache<String, Bitmap> {
private static final String TAG = "LruImageCache";
private static final int DEFAULT_CACHE_SIZE = 20 * 1024 * 1024;
public LruImageCache() {
this(DEFAULT_CACHE_SIZE);
}
public LruImageCache(int maxSize) {
super(maxSize);
}
@Override
protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
Log.d(TAG, "cache removed: " + key);
}
@Override
protected Bitmap create(String key) {
// 从本地、网络获取图片
return loadImageFromIO(key);
}
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getAllocationByteCount();
}
}
//使用
Bitmap b = LruImageCache.get("http://image-path");
Android中的LruCache的原理和使用的更多相关文章
- Android中图像变换Matrix的原理、代码验证和应用(一)
第一部分 Matrix的数学原理 在Android中,如果你用Matrix进行过图像处理,那么一定知道Matrix这个类.Android中的Matrix是一个3 x 3的矩阵,其内容如下: Matri ...
- Android 中View的工作原理
Android中的View在Android的知识体系中扮演着重要的角色.简单来说,View就是Android在视觉的体现.我们所展现的页面就是Android提供的GUI库中控件的组合.但是当要求不能满 ...
- Android中微信抢红包插件原理解析和开发实现
一.前言 自从去年中微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...
- Android中图像变换Matrix的原理、代码验证和应用(三)
第三部分 应用 在这一部分,我们会将前面两部分所了解到的内容和Android手势结合起来,利用各种不同的手势对图像进行平移.缩放和旋转,前面两项都是在实践中经常需要用到的功能,后一项据说苹果也是最近才 ...
- Android中SensorManager.getRotationMatrix函数原理解释
SensorManager是Android中的一个类,其有一个函数getRotationMatrix,可以计算出旋转矩阵,进而通过getOrientation求得设备的方向(航向角.俯仰角.横滚角). ...
- Android中典型的ROOT原理(5)
ROOT的作用 Customization 用户的个人定制,如删除一些预安装,定制开机动画等. 特权操作 所有需要特权操作的基本都是要通过ROOT,这也是ROOT的初衷. ROOT的第一步:寻找漏洞并 ...
- Android中线程间通信原理分析:Looper,MessageQueue,Handler
自问自答的两个问题 在我们去讨论Handler,Looper,MessageQueue的关系之前,我们需要先问两个问题: 1.这一套东西搞出来是为了解决什么问题呢? 2.如果让我们来解决这个问题该怎么 ...
- Android中图像变换Matrix的原理、代码验证和应用(二)
第二部分 代码验证 在第一部分中讲到的各种图像变换的验证代码如下,一共列出了10种情况.如果要验证其中的某一种情况,只需将相应的代码反注释即可.试验中用到的图片: 其尺寸为162 x 251. 每种变 ...
- [转]Android中handler机制的原理
Andriod提供了Handler 和 Looper 来满足线程间的通信.Handler先进先出原则.Looper类用来管理特定线程内对象之间的消息交换(MessageExchange). 1)Loo ...
随机推荐
- day04 python入门(变量,基本数据类型)
python入门学习 来自egon的学习套路 在每次遇到一个新事物的时候,要学三步: xxx是什么? 为什么要有xxx? 大前提:python中所有出现的语法都是为了让计算机能够具有人的某一个功能 ...
- Java标识符/数据类型,规范等详解
Java标识符 类名/变量名/方法名都称之为标识符. Java 所有的组成部分都需要名字.类名.变量名以及方法名都被称为标识符. 关于 Java 标识符,有以下几点需要注意: 所有的标识符都应该以字母 ...
- Jmeter系列(43)- 详解 Jmeter 图形化 HTML 压测报告之 Charts 模块
如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html Charts 介绍 包含了各种详细信息 ...
- MYSQL 之 JDBC(九):增删改查(七)DAO的补充和重构
DAO重构后的代码 package com.litian.jdbc; import org.apache.commons.beanutils.BeanUtils; import java.sql.*; ...
- Guava集合--Immutable(不可变)集合
所谓不可变集合,顾名思义就是定义了之后不可修改的集合. 一.为什么要使用不可变集合 不可变对象有很多优点,包括: 当对象被不可信的库调用时,不可变形式是安全的: 不可变对象被多个线程调用时,不存在竞态 ...
- Apache Kylin v3.1.0 重点功能推介
Apache Kylin v3.1.0 已于上周正式发布,其中包含了许多值得一试的新功能,本文选择了 Presto 查询下压引擎.Flink 构建引擎.Kylin on Kubernetes 解决方案 ...
- day3 python数据类型转换及变量的缓存机制
类型转换 1,强制类型转换 1.1 number的转换(int,float,bool,complex) num1 = 10 num2 = 10.6 num3 = True num4 = 3 + 4j ...
- 据说比Spring快44倍的web开发框架,不妨试试
该框架称为:**light-4j **.官方网站简介:A fast, lightweight and more productive microservices framework.很简单,翻译过来就 ...
- maven 将jar包添加本地仓库源
有如下jar包 zxing3.2.1.jar zxingcore.jar QRCode.jar 存在于本机目录 D:\Program Files\eclipse_workspace\webapp\We ...
- MSF查找提权exp
0x01:介绍 在拿到一个反弹shell后,下一步可以用metaspolit的内置模块Local Exploit SuggesterLocal-exploit-suggester的功能就如它的名字一样 ...