今天qiugong兄弟喜得贵子,升级当爸,开心之余,决定写篇博客庆祝下,之前忙着一些琐事,自从上篇博客最新Retrofit + RxJava + MVP 发表后,原本打算写上十篇左右贴子来讲述之前传到github上的framework,却拖了一个多月还未动笔,惭愧。
对于日常开发中,有时候很多接口并不需要多次调用,只需要访问一次就够,比如省、市、区三级目录,如果把这个放在本地,处理不当就会卡死,之前想用文本存储,文本中放json,三级目录的完整json还是挺大的,好像有140kb,具体记不清了,还有一种方案就是放xml,也还是觉得不妥,处理也很麻烦,比较好的方案,个人推荐使用容器缓存。
先上代码:
/**
* 配置过期类型和时间
*
* Created by Zero on 2017/5/30.
*/
public class CacheObject {
private long timestamp;
private int period = -1;
private Object data;
/**
* @param data
* @param period -1 表示永不过期,大于0表示过期的时间,单位分钟
*/
public CacheObject(Object data, int period) {
timestamp = System.currentTimeMillis();
this.data = data;
this.period = period;
}
public Object getObject() {
return data;
}
public boolean isValid() {
if (period == -1 || System.currentTimeMillis() < (timestamp + period * 60000)) {
return true;
}
return false;
}
public void setPeriod(int period) {
this.period = period;
}
public int getPeriod() {
return period;
}
}
这里是对缓存类型和时间的配置,可以配置成永不过期,也可以配置成指定时间过期,比如有些token,在后台多少时间后便会过期,招商银行的APP就是这么做的,每次把app打入冷宫后,时间一长,矫情的她就离我而去,需要重新登录,对于省市区三级目录,这些属于常年不变的,可以使用长期缓存。
/**
* 数据请求中对cache进行管理
* Created by Zero on 2017/5/30.
*/
public class CacheManager {
private static Map<String, CacheObject> cacheMap = new HashMap<>();
/**
* 添加到cache
*
* @param key
* @param data
* @param period
*/
public static void addData(String key, Object data, int period) {
CacheObject cacheObject = getData(key);
if (cacheObject != null) {
/**
* 如果类型不同,便重新加入到缓存中
*/
if (period != cacheObject.getPeriod()) {
cacheObject.setPeriod(period);
/**
* 移除老的value
*/
removeInvalidData(key);
/**
* 重新putvalue
*/
cacheMap.put(key, cacheObject);
}
} else {
cacheObject = new CacheObject(data, period);
cacheMap.put(key, cacheObject);
}
}
/**
* 获取cache
*
* @param key
* @return
*/
public static CacheObject getData(String key) {
CacheObject cacheObject = cacheMap.get(key);
if (cacheObject != null) {
/**
* 判断缓存是否过期
*/
if (cacheObject.isValid()) {
return cacheObject;
} else {
removeInvalidData(key);
}
}
return null;
}
/**
* 移除过期的key
*
* @param key
*/
public static void removeInvalidData(String key) {
if (cacheMap.containsKey(key)) {
cacheMap.remove(key);
}
}
}
此类主要用于缓存,把请求到的数据,以 Url 为唯一标识并作为 key 建立缓存,首先通过 key 获取缓存中是否存在缓存,如果没有,便去请求数据,把得到的结果缓存到容器中,如果之前已经建立过缓存,便直接从容器中读取缓存,减小服务器压力,在并发量大的时候,大大减小服务器压力。此处使用的是 map 缓存,采用 map ,主要原因是键值对可以更高效的为我们服务,key–>value。
addData方法,顾名思义,添加缓存,看下源码,并不是无脑的添加,还是先做判断是否有缓存,上述已经提到,如果没有缓存便会添加到容器中,如果有,便会判断缓存时间类型是否有改变,如果有没有改变,便不会添加到缓存中,如果有改变,便会先移除老的数据,把新数据加入进去。
项目已上传,戳此进入github。