1. 按照惯例先来代码传送门DiskLruCacheDemo
2. 效果图
效果图
3. DiskLruCache简介
DiskLruCache是JakeWharton大神的杰作,它采用的是LRU算法,通过LRU算法对缓存进行管理,以最近最少使用作为管理的依据,删除最近最少使用的数据,保留最近最常用的数据
4. DiskLruCache使用
4.1 DiskLruCache虽然得到Google认证,但是SDK中还没有加入,所以使用时需要我们手动添加依赖
compile 'com.jakewharton:disklrucache:2.0.2'?
4.2 创建DiskLruCache对象
4.2.1 DiskLruCache不能通过构造方法来创建,它通过open方法来创建自身。
try {
if (mDiskLurCache != null) {
mDiskLurCache.close();
mDiskLurCache = null;
}
int appVersionCode = getAppVersionCode(mContext);
File cacheFile = getCacheFile(mContext, fileName);
mDiskLurCache = DiskLruCache.open(cacheFile, appVersionCode, 1, CACHE_MAXSIZE);
} catch (IOException e) {
}
参数说明
- directory 数据缓存地址
- appVersion 版本号,当版本号改变数据会被清除
- valueCount:同一个key可以对应多少文件
- maxSize:最大可以缓存的数据量
4.2.2 设置DiskLruCache的存储路径
private File getCacheFile(Context context, String fileName) {
String cachePath = "";
//判读sd卡是否可用
if ((Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
|| !Environment.isExternalStorageRemovable())
&& context.getExternalCacheDir() != null) {
//获取有sd卡时的路径,该路径在程序卸载时会被删除
cachePath = context.getExternalCacheDir().getPath();
} else {
//获取无sd卡时的路径,该路径在程序卸载时会被删除
cachePath = context.getCacheDir().getPath();
}
//File.separator 分隔符
return new File(cachePath + File.separator + fileName);
}
设置DiskLruCache的存储路径时需要对sd卡可用进行判断,并且路径和我们的程序相关,程序卸载时该路径下的文件就会被删除
4.2.3 其他参数就不多说了
4.3 数据缓存进磁盘
这里缓存DiskLruCache.Editor对象来进行数据缓存
if (mDiskLurCache != null) {
try {
String md5Key = getMD5(key);
DiskLruCache.Editor edit = mDiskLurCache.edit(md5Key);
return edit;
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
这里和SharedPreferences存数据相似,注意一点的是key需要加密,我用的是MD5的方式进行加密
获取到Editor之后就需要用流对数据进行写入,这里不多说了直接贴代码
public void put(String key, Object object) {
ObjectOutputStream oos = null;
DiskLruCache.Editor editor = null;
OutputStream outputStream = null;
try {
editor = editor(key);
if (editor == null) {
return;
}
outputStream = editor.newOutputStream(0);
oos = new ObjectOutputStream(outputStream);
oos.writeObject(object);
oos.flush();
editor.commit();
} catch (IOException e) {
e.printStackTrace();
try {
if (editor != null)
editor.abort();
} catch (IOException e1) {
e1.printStackTrace();
}
} finally {
try {
if (oos != null) {
oos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
}
}
}
上面的代码是存入Object类型的数据,需要注意的是我们在存的时候要对该类进行序列话操作,不然存入的数据就会为空
public void put(String key, String value) {
DiskLruCache.Editor editor = null;
BufferedWriter writer = null;
OutputStream os = null;
try {
editor = editor(key);
if (editor == null) {
return;
}
os = editor.newOutputStream(0);
writer = new BufferedWriter(new OutputStreamWriter(os));
writer.write(value);
writer.flush();
editor.commit();
} catch (IOException e) {
e.printStackTrace();
try {
if (editor != null)
editor.abort();
} catch (IOException e1) {
e1.printStackTrace();
}
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
上面代码是存入String类型的数据
4.4 从磁盘中读取数据
读取数据需要 DiskLruCache.Snapshot对象,直接贴代码
public DiskLruCache.Snapshot snapshot(String key) {
String md5Key = getMD5(key);
if (mDiskLurCache != null) {
try {
DiskLruCache.Snapshot snapshot = mDiskLurCache.get(md5Key);
return snapshot;
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
获取到DiskLruCache.Snapshot之后,通过DiskLruCache.Snapshot对象获取InputStream
private InputStream getInputStream(String key) {
DiskLruCache.Snapshot snapshot = snapshot(key);
if (snapshot == null) {
return null;
}
InputStream inputStream = snapshot.getInputStream(0);
return inputStream;
}
然后通过InputStream读取数据
public <T> T getObjectCache(String key) {
InputStream inputStream = getInputStream(key);
ObjectInputStream ois = null;
T object = null;
if (inputStream == null) {
return null;
}
try {
ois = new ObjectInputStream(inputStream);
object = (T) ois.readObject();
return object;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (ois != null) {
ois.close();
}
} catch (IOException e) {
}
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
读取Object类型数据。
public String getStringCache(String key) {
InputStream inputStream = getInputStream(key);
InputStreamReader inputStreamReader = null;
BufferedReader in = null;
if (inputStream == null) {
return null;
}
try {
inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
in = new BufferedReader(inputStreamReader);
StringBuilder buffer = new StringBuilder();
String line;
try {
while ((line = in.readLine()) != null) {
buffer.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return buffer.toString();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} finally {
try {
if (in != null)
in.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (inputStreamReader != null)
inputStreamReader.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (inputStream != null)
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
读取String类型数据
5. 工具类的使用
1.创建对象
DiskLruCacheUtil mDiskLruCacheUtil = new DiskLruCacheUtil(this,"DISK_LRU_CACHE");
第二个参数就是文件名了
2.存数据
mDiskLruCacheUtil.put("STRING","我是string类型");
mDiskLruCacheUtil.put("object",userBean);
- 读数据
String string = mDiskLruCacheUtil.getStringCache("STRING");
UserBean userBean =mDiskLruCacheUtil.getObjectCache("object");
6. 结语
有了工具类数据缓存就会变得非常简单,最后祝各位生活愉快
最后代码传送门DiskLruCacheDemo