android有什么好用的缓存框架吗

做Android应用开发的同学们相信对“缓存”这个词不陌生缓存可能有多方面的概念,这里大概列举下程序开发的缓存大概有哪些:

如volley请求库便是通过服务端的“Cache-Control”和“max-age”来告诉客户端有没有缓存以及缓存的时间,也是推荐的使用方式但是需要服务端配合,比较灵活

  • 2.客户端直接控制缓存

有些时候不需要服務端来支持的话,客户端可以直接做一层缓存思路就是请求之后把数据缓存在本地,最常见的是直接以文件缓存在本地就好了当然你鈳以缓存在本地的sqlite,以sqlite文件的形式缓存数据处理更灵活点然后客户端自己处理缓存的时间,过期则直接清除数据对于一些不太经常变囮的页面,采用这种缓存可以减少客户端流量同时减少服务器并发量。

对于一些新闻类或者timeline这种数据变化是非常频繁的,针对这种情況可能就不太适合设置缓存时间这种情况可以考虑让页面每次进来都会自动刷新一次以获取最新数据,如果网络不好或者断开时可以直接读取本地缓存增加用户体验。当然如果想要更复杂的处理可以配合时间来判断当前页面要不要刷新

今天就介绍一种简易的缓存框架,使用起来非常简单

ASimpleCache 是一个为android制定的 轻量级的 开源缓存框架。轻量到只有一个java文件(由十几个类精简而来)

最后此项目的开源地址: 

2018年过去了很久之前就希望自己鈳以潜心研究源码,研究技术但是空闲时间不是看电影,就是玩游戏都没有认真看技术方面的东西感觉很内疚2019年一定要好好的研究端囸态度,认真学习技术

有时候Android应用中要获取比较大的数据,比如说图片流短视频流等,如果每次都从网络上去请求那么响应速度很慢的,用户体验不好

如果把服务器拉下来的数据保存在本地数据库中,在服务器数据并没有发生改变的时候直接从本地中获取数据,這就是Android中的二级缓存比直接每次从服务器中拉取数据多了本地的存储。二级缓存原理如下图:

由上图可知在二级缓存中,Android中的activity请求数據时都是先从本地数据库中拿数据,当然activity并不知道管获取的数据是从本地数据库中还是服务器中本地数据和服务器数据可以统一为数據源。当服务器数据有改变的时候会从服务器中拉取数据但是拉取的数据先存在本地数据库中然后再由本地数据库返回给activity。

二级缓存的缺点是每次activity的数据都要从本地数据库中获取虽然从本地数据库中获取的数据速度要比从服务器获取的速度快,但是每次读写数据库进行嘚IO操作也是很花费时间的

三级缓存在二级缓存的基础上加了一个内存。从服务器获取的数据库除了存在本地数据库中同时在内存中也保存一份,这样当activity请求数据时可以先从内存中获取数据如果内存中没有数据,或者内存中数据已经脏了的情况下取本地数据库中的数據。当本地数据库的数据也脏了的情况下取服务器数据取回的数据存一份本地数据库,存一份内存中三级缓存原理如下图:

上面的图畫的比较乱,流程是:当activity要请求数据时1、先检查内存中缓存数据如果内存中有数据并且数据不脏时直接返回内存中的数据
2、如果内存中無数据并且数据不为脏时向本地数据库中请求数据,并且将请求的数据写入到内存中再将内存中的数据返回。
3、如果内存和本地数据库Φ都没有数据返回也就是内存中无数据并且数据为脏时,向服务器请求数据服务器返回的数据,保存到本地数据库并且保存一份到内存最后将内存中的数据返回。

由三级缓存的原理可以实现三级缓存的框架数据的来源有三个地方,内存本地数据库,服务器但是應用层并不关心数据来自哪里,所以要定义一个数据仓库里面处理数据逻辑,当activity请求数据时直接由数据仓库来返回数据
定义数据仓库の前可以定义一个数据来源接口,这个接口定义数据的操作比如插入数据,删除数据返回数据等。类图:

}//多个任务获取数据回调 }//获取單个任务回调

上面定义了数据源类TasksDataSource在这个类中定义了获取任务或者任务组的回调已经获取任务,存储任务删除任务,刷新任务的方法其中的task是自定义的应用中要用到的数据类型,这里定义的比较简单:

因为Task要写入到本地数据库所以mId作为唯一键。 有了数据来源再定义夲地数据仓库数据仓库向activity提供数据,并且实现上面的三级缓存原理数据仓库中处理三种来源的数据,并将最后的结果返回 数据仓库TasksRepository

關注+点赞,+qq群:即可获取更多有关安卓开发的资料(面试资源与经验总结,BAT内推高级UI、性能优化、架构师课程、NDK、混合式开发全方 面嘚 Android高级实践技术讲解以及在线答疑等。)!

  • 缓存是分布式系统中的重要组件主要解决高并发,大数据场景下热点数据访问的性能问题。提供高性能的数据快速访问 一...

  • 缓存是分布式系统中的重要组件,主要解决高并发大数据场景下,热点数据访问的性能问题提供高性能的数据快速访问。 一...

  • 潘祉宜 0、今天是2018年2月14日阴历十二月二十九,星期三京津今日限号2和7。天津天...

  • 微淘百课是一款基于社群 内容的知识型产品微淘百课拥有丰富和优质的讲师群体,能为社群的发展提供健康的内容大大增强...

缓存是存取数据的临时地因为取原始数据代价太大了,加了缓存可以取得快些。缓存可以认为是原始数据的子集它是从原始数据里复制出来的,并且为了能被取回被加上了标志。

在android开发中经常要访问网络数据比如大量网络图片,如果每次需要同一张图片都去网络获取这代价显然太大了。可以栲虑设置本地文件缓存和内存 缓存存储从网络取得的数据;本地文件缓存空间并非是无限大的,容量越大读取效率越低可设置一个折Φ缓存容量比如10M,如果缓存已满我们需要采用合 适的替换策略换掉一个已有的数据对象,并替之已一个新的数据对象;内存缓存作为最先被读取的数据应该存储那些经常使用的数据对象,且内存容量有限内存 缓存的容量也应该限定。依照这样的做法取得一个图片(總图片数为N)的流程应该是这样的:

a.先在内存缓存取(设存储K个),若取到则返回(命中率为K/N时间为tA),否则进行b;

b.在本地文件缓存(设能存储M个)中取若取到则返回并更新内存缓存(命中率为(M-K)/N,时间为tB),否则进行c;

c.通过网络下载图片并更新本地文件缓存和内存缓存(命中率为(N-M)/N,时间为tC);

取一张图片的时间期望为:W = tA * (K/N) + tB * (M-K)/N + tC * (N-M)/N 其中tA < tB < tC ,为使W代价小,即尽可能快的取得数据我们应该提高内存缓存的命中率和本地文件緩存的命中率,但两者的容量都是有限制的所以必须使用适合替换算法来更 新两者所存储的对象。选择合适的替换算法是缓存的难点所茬


对每个缓存对象计算他们被使用的频率。把最不常用的缓存对象换走

把最近最少使用的缓存对象给换走。总是需要去了解在什么时候用了哪个缓存对象。如果有人想要了解为什么总能把最近最少使用的对象踢掉是非常困难的。浏 览器就是使用了LRU作为缓存算法新嘚对象会被放在缓存的顶部,当缓存达到了容量极限我会把底部的对象踢走,而技巧就是:我会把最新被访问的缓存对 象放到缓存池嘚顶部。

所以经常被读取的缓存对象就会一直呆在缓存池中。可以用数据或者链表实现其改进算法有LRU2 和 2Q。

把被两次访问过的对象放入緩存池当缓存池满了之后,我会把有两次最少使用的缓存对象踢走因为需要跟踪对象2次,访问负载就会随着缓存池的增加而增加 如果用在大容量的缓存池中,就会有问题另外,还需跟踪那么不在缓存的对象因为他们还没有被第二次读取。这比LRU好

把被访问的数据放到LRU的缓存中,如果该对象再一次被访问就把他转移到第二个更大的LRU缓存。替换掉缓存对象是为了保持第一个缓存池是第二个缓存池 的1/3当缓存的访问负载是固定的时候,把 LRU 换成 LRU2就比增加缓存的容量更好。这种机制使得该算法比 LRU2 更好

这种算法介于 LRU 和 LFU 之间,由2个 LRU 组成苐一个,也就是 L1包含的条目是最近只被使用过一次的,而第二个 LRU也就是L2,包含的是最近被使用过两次的条目因此,L1 放的是新的对象而 L2 放的是常用的对象。该算法是是性能最好的缓存算法之一能够自调,并且是低负载的保存着历史对象,这样就可以记住那些被迻除的对象,同时也可以看到 被替换掉的对象是否可以留下,取而代之的是替换别的对象该算法记忆力很差,但是很快适用性也强。

该算法与 LRU是对应的它替换掉最近最多被使用的对象,你一定会问为什么原因是,当一次访问过来的时候有些事情是无法预测的,並且在缓存系统中找出最少最近 使用的对象是一项时间复杂度非常高的运算该算法在数据库内存缓存中很见!每当一次缓存记录的使用,会把它放到栈的顶端当栈满了的时候,会把栈顶的对象 给换成新进来的对象!

这是一个低负载的算法并且对缓存对象的管理要求不高。通过一个队列去跟踪所有的缓存对象最近最常用的缓存对象放在后面,而更早的缓存对象放在前面当缓存容量满时,排在前面的緩存对象会被踢走然后把新的缓存对象加进去。很快但是不适用。

改进的FIFO算法比 FIFO 好的地方是改善了 FIFO 的成本。一样是在观察队列的前端但是很FIFO的立刻替换不同,它会检查即将要被踢出的对象有没有之前被使用过的标志(1一个bit表示)如果没有被 使用过,就把他换出;否则把这个标志位清除,然后把这个缓存对象当做新增缓存对象加入队列你可以想象就这就像一个环队列。当再一次在队头碰到这个對象 时由于它已经没有标志位,可以立刻就它换出在速度上比FIFO快。

这是一个更好的FIFO也比 second chance更好。因为它不会像second chance那样把有标志的缓存对潒放到队列的尾部但是也可以达到second chance的效果。它持有一个装有缓存对象的环形列表头指针指向列表中最老的缓存对象。当缓存miss发生并且沒有新的缓存空间时它会根据指针指向 的缓存对象的标志位去决定应该怎么做。如果标志是0直接用新的缓存对象替代这个缓存对象;洳果标志位是1,把头指针递增然后重复这个过程,直到新的缓 存对象能够被放入

通过绝对的时间周期去失效那些缓存对象。对于新增嘚对象保存特定的时间。很快但不适用。

通过相对时间去失效缓存对象的;对于新增的缓存对象保存特定的时间,比如是每5分钟烸天的12点。

被管理的缓存对象的生命起点是在这个缓存的最后被访问时间算起很快,不太适用

缓存算法主要考虑到了下面几点:

成本。如果缓存对象有不同的成本应该把那些难以获得的对象保存下来。

容量如果缓存对象有不同的大小,应该把那些大的缓存对象清除这样就可以让更多的小缓存对象进来了。

时间一些缓存还保存着缓存的过期时间。电脑会失效他们因为他们已经过期了。


3.增强用户體验的图片缓存框架

我要回帖

 

随机推荐