在项目开发中有一个需求,每次启动APP的时候都需要向服务器请求参数,然后进入到某个界面时直接取出来,
而不去请求网络,实现更好的用户体验,但是这些数据只能保存一定时间,而且当APP关闭时,这些数据就得销毁,
查了半天API貌似没看到定时缓存(不确定到底有没有),这里就自己模拟了一个,注释已经很详细了。。。
看代码:
package com.memorycache;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import com.bxg.news.utils.DateUtils;
/**
* 把一些数据缓存到内存,然后设置定时清理功能
*
* @author JiangYueSong
*
*/
public class CacheContainer {
/**
* 缓存的map
*/
private static Map<String, Object> cacheFile = new LinkedHashMap<String, Object>();
/**
* 缓存只能占用的最大堆内存
*/
private static long limit = 1000000;
/**
* 缓存已经使用的大小
*/
private static long usedCache = 0;
/**
* 从缓存中取
*
* @param key
* @return
* @throws Exception
*/
synchronized public static Object getFromCacheFile(String key) {
String tempkey = key + "DATE"; // 为缓存的数据添加过期时间
Object obj = cacheFile.get(tempkey); // 获得数据
if (obj == null) { // 判断是否为空
return null;
}
Date d = new Date();
int time = d.compareTo(DateUtils.strToDateLong(String.valueOf(obj))); // 把保存的时间与现在手机上的时间对比
if (time >= 0) { // 如果超出,则删除
removeValueByKey(key, tempkey);
return null;
} else {
return cacheFile.get(key);
}
}
/**
* 从缓存中移除数据
*
* @param key
*/
public static void removeValueByKey(String... key) {
long start = 0;
long end = 0;
// 先垃圾回收
System.gc();
start = Runtime.getRuntime().freeMemory();
for (int i = 0; i < key.length; i++) {
if (cacheFile.containsKey(key[i]))
cacheFile.remove(key[i]);
}
System.gc();
end = Runtime.getRuntime().freeMemory();
usedCache -= (end - start);
}
/**
* 保存数据岛map
*
* @param key
* key
* @param obj
* value
* @param holdTime
* 保存时间
*/
public static void saveValueByKey(String key, Object obj, int holdTime) {
judgeContainer(); // 判断容器是否超出限制大小
long start = 0;
long end = 0;
// 先垃圾回收
System.gc();
start = Runtime.getRuntime().freeMemory();
String subKey = "";
if (key.length() > 5) { // 由于为每一个key添加了一个key+DATE作为时间戳,所以这里判断是否存在这个时间戳
subKey = key.substring(key.length() - 5);
} else {
subKey = key;
}
if (subKey.contains("DATE")) {
if (cacheFile.containsKey(key)) {
removeValueByKey(key);
removeValueByKey(key.substring(0, key.length() - 4));
}
}
cacheFile.put(
key + "DATE",
DateUtils.getPreTime(DateUtils.getStringDate(),
String.valueOf(holdTime)));
cacheFile.put(key, obj);
System.gc();
end = Runtime.getRuntime().freeMemory();
usedCache += (end - start);
}
/**
* 判断容器大小是否超出内存
*/
synchronized public static void judgeContainer() {
while (usedCache >= limit) {
cacheFile.remove(cacheFile.size() - 1);
}
}
/**
* 强制保存key value到map,如果之前存在则覆盖
*
* @param key
* @param obj
* @param holdTime
*/
synchronized public static void saveMap2CacheFile(String key, Object obj,
int holdTime) {
judgeContainer();
// 首先放入时间的key给的key做关联
saveValueByKey(key, obj, holdTime);
}
/**
* 放入缓存中,并判断是否存在,不使用
*
* @param file
* @param holdTime
* @return
*/
synchronized public static void putMap2CacheFile(String key, Object obj,
int holdTime) {
judgeContainer();
saveValueByKey(key, obj, holdTime);
}
/**
* 放入缓存中,并判断是否存在,不使用
*
* @param file
* @param holdTime
* @return
*/
synchronized public static void putMap2CacheFile(Map<String, Object> file,
int holdTime) {
judgeContainer();
for (String key : file.keySet()) {
saveValueByKey(key, file.get(key), holdTime);
}
}
}