为了使用方便,我将android内常用的缓存方式进行了封装:
(一)单独封装
(1)SharePreferences
这个东西最麻烦的是要传一个context,现封装为不需要context,不需要传mode,使用方式变为:
存:
ShareUtils.resetShare("名称")
.set("a","abc")
.set("b",123)
.set("c",true)
.commit();
取:
boolean c = ShareUtils.resetShare("名称").getBoolean("c");
当然,你可以把getInstance改为静态,然后直接用resetShare,更为方便:
ShareUtils.resetShare(“名称”).getBoolean(“c”)
(2)Properties
这个其实java的,好处是不限定为应用存储区,可以放在sdcard,但是有些手机已经不支持它的非String类型,(原因不知道,测试结果是这样),这部分也重新封装了一下。
用法,存:
PropertiesUtil.resetProperties()
.put("version",1)
.put("dbVersion",2)
.put("versionName",1.0)
.put("isLatestVersion",true)
.put("appName","CacheForAndroid")
.save(saveFile);
取:
PropertiesUtil savedProperties = PropertiesUtil.resetProperties().loadProperties(saveFile);
int version = savedProperties.getInt("version");
int dbVersion = savedProperties.getInt("dbVersion");
double versionName = savedProperties.getDouble("versionName");
boolean isLatestVersion = savedProperties.getBoolean("isLatestVersion");
ToastUtil.shorts("version="+version);
ToastUtil.shorts("dbVersion="+dbVersion);
ToastUtil.shorts("versionName="+versionName);
ToastUtil.shorts("isLatestVersion="+isLatestVersion);
(3)序列化对象
存:
User user = getSaveUser();
File saveFile = getSaveFile();
SerialUtil.saveObjectInFile(user,saveFile);
取:
File saveFile = getSaveFile();
User user = SerialUtil.restoreObjectByFile(saveFile,new User());
showUserContent(user);
数据库用了greendao,因为很多时候没有主键,还是要用SQL语句写= =,不过作者已经封装的很好了,只有把获取dao的时候做个封装,大致如下:
public class DBManager {
private static final String PWD = "123";
private static DaoSession encryptedSession;
private static final String DB_NAME = "my.db";
public static DaoSession getSession(){
if(encryptedSession == null){
DBHelper dbHelper = new DBHelper(CacheForAndorid.getSuperContext(),DB_NAME,null);
encryptedSession = new DaoMaster(dbHelper.getEncryptedWritableDb(PWD)).newSession();
}
return encryptedSession;
}
private static DBUserDao userDao;
public static DBUserDao getMyDBDao(){
if(userDao == null){
userDao = getSession().getDBUserDao();
}
return userDao;
}
private static DBUserNoKeyDao noKeyDao;
public static DBUserNoKeyDao getNoKeyDao(){
if(noKeyDao == null){
noKeyDao = getSession().getDBUserNoKeyDao();
}
return noKeyDao;
}
private static CacheUserDao cacheUserDao;
public static CacheUserDao getCacheUserDao(){
if(cacheUserDao == null){
cacheUserDao = getSession().getCacheUserDao();
}
return cacheUserDao;
}
}
注意这里把session也封装了一层,因为无主键时删除和更新必须要写sql,大概是这样:
DBManager.getSession().getDatabase().execSQL(“delete from xx”);
如果不需要使用时可以删除掉。
(二)联合封装
我用了List+Share+数据库,因为使用了责任链,写的比较灵活,所以可以随意拆分,可扩展性也不错。
最外层,这样就可以保存到缓存了,
CacheUtil.setCacheUser(getMyCacheUser());
最外层,这样就可以从缓存取出了,
CacheUser cacheUser = CacheUtil.getCacheUser();
最主要的思想是链式传递,思路如下:
每种缓存封装为一个类,都实现如下接口:
public interface ICacheWay<T> {
void setNextCache(ICacheWay<T> nextCache);//当取出的内容为空时,继续从下一级缓存中获取
void setCacheSaveTime(long overDueTime);//超时时间,超时下一次取回强制清空
T getCache(T t);//最重要的,获取缓存
void clearCacheOverDueTime(T t);//超时清空
void saveObjInCache(T t);//保存对象到缓存
void clearCache(T t);//无条件清除缓存中的t对象
}
这样,在开始的时候都设定好下一级缓存以及超时时间,然后确定下一级:
如用集合缓存,设定时间为10*1000,下一级为SharePreferences:
ICacheWay<CacheUser> mListCache = new ListCache<>();
ICacheWay<CacheUser> mShareCache = new ShareCache<>();
mListCache.setNextCache(mShareCache);
mListCache.setCacheSaveTime(10);
CacheUser mCacheUser = mListCache.getCache(new CacheUser());
这样就可以完成二级缓存了,因为集合内获取不到时,自动从Share中再获取,如果从后面获取到结果,再保存到ListCache,这样就能达到联合的目的,是不是很灵活呢?快来用一用吧。
我的git:https://github.com/nfwuzhongdemeng/mutiCache
关于时间设定方面还不够完善,近段时间会继续更新。