Android缓存分为内存缓存和磁盘缓存。
内存缓存(LruCache)
在早期的 Android 2.x 时代,常用的缓存方式是软引用(SoftReference)和弱引用(WeakReference),如大部分的使用方式:HashMap<String url, SoftReference<Drawable>> imageCache;这种形式。从Android 2.3(Level 9)开始,垃圾回收器更倾向于回收 SoftReference 或 WeakReference 对象,这使得 SoftReference和 WeakReference 变得不是那么实用有效。
同时,到了Android 3.0(Level 11)之后,图片数据Bitmap被放置到了内存的堆区域,而堆区域的内存是由GC管理的,开发者也就不需要进行图片资源的释放工作,但这也使得图片数据的释放无法预知,增加了造成OOM的可能。
因此,在Android3.1以后,Android推出了LruCache这个内存缓存类,LruCache中的对象是强引用的。
LruCache 是 Android 3.1 开始提供的一种基于内存的缓存框架,LRU 是 Least Recently Used 的缩写,即最近最少使用。当一块内存最近很少使用的时候就会被从缓存中移除。它内部采用一个 LinkedHashMap 以强引用的方式存储外界的缓存对象,其提供了get和put方法来完成缓存的获取和添加操作,当缓存满时,LruCache 会移除较早的缓存对象,然后再添加新的缓存对象。
LruCache 是线程安全的。
-
使用 LruCache
SDK 自带,可直接使用。
注意:LruCache 从 Android 3.1 开始已经作为 android 源码的一部分维护在 android 系统中,为了兼容以前的版本, android 的 support-v4 包也提供了 LruCache 的维护。如果 App 需要兼容到 android 3.1 之前的版本就需要使用 support-v4 包中的 LruCache,如果不需要兼容到 android 3.1 则直接使用android 源码中的 LruCache 即可。
-
LruCache 常用 API
方法名 释义 LruCache(int maxSize) 实例化 Lru,需要传入缓存的最大值,这个最大值可以是个数,比如对象的个数,也可以是内存的大小 resize(int maxSize) 重置最大存储空间 get(K key) 通过 key 返回相应的 item,或者创建返回相应的 item。相应的item会移动到队列的头部,如果 item 的value没有被 cache 或者不能被创建,则返回 null。 put(K key, V value) 创建 cache 项,并将创建的项放到队列的头部 trimToSize(int maxSize) 清空 cache 空间 remove(K key) 删除 key 相应的 cache 项,返回相应的 value create(K key 当某 Item 丢失时会调用到,返回计算的相应的 value 或者 null sizeOf(K key, V value) 这个方法要特别注意,跟我们实例化 LruCache 的 maxSize 要呼应,怎么做到呼应呢,比如 maxSize 的大小为缓存的个数,这里就是 return 1就 ok,如果是内存的大小,如果5 M,这个就不能是个数了,就需要覆盖这个方法,返回每个缓存 value 的size大小,如果是 Bitmap,这应该是 bitmap.getByteCount(); evictAll() 清空 cache evictionCount() 返回被回收的数量 snapshot() 返回当前cache的副本,从最近最少访问到最多访问
磁盘缓存(DiskLruCache)
DiskLruCache 不同于 LruCache,LruCache 是将数据缓存到内存中去,而 DiskLruCache 是外部缓存,例如可以将网络下载的图片永久的缓存到手机外部存储中去,并可以将缓存数据取出来使用。
DiskLruCache 不是 Android 自带类,是大神 JakeWharton 开源的,但是得到了官方推荐。DiskLruCache 没有编写到 SDK 中,如需使用可直接 copy 这个类到项目中去。
-
使用 DiskLruCache
-
直接代码中引用
compile 'com.jakewharton:disklrucache:2.0.2'
-
DiskLruCache 常用 API
方法名 | 释义 |
---|---|
DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize) | DiskLruCache 实例化方法。作用是打开一个缓存目录,如果没有则首先创建它。directory:指定数据缓存地址;appVersion:APP版本号,当版本号改变时,缓存数据会被清除 ;valueCount:同一个key可以对应多少文件 ;maxSize:最大可以缓存的数据量。 |
Editor edit(String key) | 通过key可以获得一个DiskLruCache.Editor,通过Editor可以得到一个输出流,进而缓存到本地存储上。 |
void flush() | 强制缓冲文件保存到文件系统 |
Snapshot get(String key) | 通过key值来获得一个Snapshot,如果Snapshot存在,则移动到LRU队列的头部来,通过Snapshot可以得到一个输入流InputStream |
long size() | 缓存数据的大小,单位是byte |
boolean remove(String key) | 根据key值来删除对应的数据,如果该数据正在被编辑,则不能删除 |
void delete() | 关闭缓存并且删除目录下所有的缓存数据,即使有的数据不是由DiskLruCache 缓存到本目录的 |
void close() | 关闭DiskLruCache,缓存数据会保留在外存中 |
boolean isClosed() | 判断DiskLruCache是否关闭,返回true表示已关闭 |
File getDirectory() | 缓存数据的目录 |
网友评论