在Android APP开发过程中有时候会用到列表来展示数据,如果只是展示很少的数据直接new一个list进行保存就可以了。如果在进行加载大量数据的时候只是单纯的加载到内存中,也就难免会出现卡顿现象。这次我就仿照别人的实现思路来完成内存的缓存和磁盘中的缓存实现RecycleVIew的加载很多的数据。
一、LruCache和DisLruCache简介
Lru全称是Least Recently Used也就是近期最少使用的意思,LruCache就是使用了近期最少使用算法,将最近不使用的对象从内存中释放掉。LruCache实现了内存中的缓存,而DisLruCache则是磁盘中的缓存。他们使用同样的算法,只是缓存地方不一样。下面来讲解我的实现过程,由于RecycleView不是重点,只有简单的几行代码,想要了解更多的相关只是,可自行google。
二、使用DiskLruCache实现数据在磁盘的缓存
由于我要实现在读取缓存的过程中如果读取不到数据我要到磁盘读取数据,因此我先进行磁盘数据的存储和读取的实现。这里使用DiskLruCache实现数据的磁盘缓存,也可以使用数据实现,我这里就不说使用数据缓存的实现了。
1、定义DiskLruCacheManage的磁盘管理类
/**
* @param context
* @param name 缓存路径的名字
*/
public DiskLruCacheManage(Context context, String name) {
this.context= context;
this.name = name;
openDiskCache();
}
这里我需要在生命这个管理类的地方传一个上下文本,一个文件名进来初始化全局变量。openDiskCache()是本类中的一个重要方法,我要在这里进行创建一个缓存文件,将数据写入穿件好的缓存文件。实现如下
private void openDiskCache() { try { File cacheDir = getDiskCacheDir(context, name); if (!cacheDir.exists()) { cacheDir.mkdir(); } mDiskLruCache = DiskLruCache.open(cacheDir, getAppVersion(context), 1, DISK_CACHE_MAX_SIZE); } catch (IOException e) { e.printStackTrace(); } }这里主要是实现缓存文件的创建,然后使用DiskLruCache的方法打开文件。这里有必要说明一下DiskLruCache的open方法的参数,源码如下
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
这是一个静态方法,返回一个DiskLruCache对象,参数作如下介绍
- directory,就是在进行open之前创建的文件的路径
- appVersion,当前APP的版本号,如果APP的版本号有更新这会清空缓存文件
- valueCount,指定同一个key可以对应多少个缓存文件,一般都是传1,这样key和value一一对应
- maxSize,缓存文件的大小,单位是字节,所以一般定义的时候用M*1024Kb*1024B
2、保存数据功能的实现
经过DiskLruCache的open方法操作过后就有了操作文件的对象mDiskLruCache,然后就可以进行数据保存功能的实现
public <T> void saveDataToDisk(T t, Class calss, final String key) {
final String jsonStr = GsonFactory.getInstance().toJson(t, calss);
Observable.empty()
.subscribeOn(Schedulers.io())
.subscribe(new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {
MyLog.i("*****************************1");
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
MyLog.i("*****************************2");
}
}, new Action() {
@Override
public void run() throws Exception {
DiskLruCache.Editor editor;
if (mDiskLruCache.isClosed()){
openDiskCache();
}
editor = mDiskLruCache.edit(key);
if (editor != null) {
OutputStream outputStream = editor.newOutputStream(0);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));
bw.write(