簡(jiǎn)介
目前大多數(shù)緩存框架都是用Java序列化的方式實(shí)現(xiàn)的持久化存儲(chǔ)羹蚣,我們自己公司的項(xiàng)目也是這么做的摄职,功能全面而且效率也高几颜, 使用起來(lái)得心應(yīng)手脸候,但是有一個(gè)小問(wèn)題穷娱,如果數(shù)據(jù)結(jié)構(gòu)發(fā)生變化,尤其是原字段的數(shù)據(jù)類(lèi)型發(fā)生變化纪他,在加載緩存時(shí)會(huì)出現(xiàn)異常鄙煤,即便寫(xiě)了序列號(hào)也沒(méi)有用。還有一個(gè)小問(wèn)題就是存儲(chǔ)文件稍微有一點(diǎn)大茶袒,于是在和同事交流過(guò)程中我有了一個(gè)新想法梯刚,能不能用json實(shí)現(xiàn)緩存? 我當(dāng)時(shí)大致的思路是這樣的:
- 對(duì)象bean -> Json -> String -> 壓縮String -> 存儲(chǔ)
- 讀取 -> 壓縮String -> String -> Json -> 對(duì)象bean
經(jīng)過(guò)一番嘗試薪寓,發(fā)現(xiàn)是可行的亡资,于是就誕生了這個(gè)JsonCache澜共。
比較
這種方式和序列化方式相比,主要是解決了上面提到的兩個(gè)問(wèn)題锥腻,但是它也有缺點(diǎn)嗦董。
- 它的緩存文件要小,尤其是數(shù)據(jù)較大并且重復(fù)度高的時(shí)候瘦黑,它的緩存文件要比序列化文件小幾十倍京革,當(dāng)然這種情況比較極端,通常文件小兩倍左右幸斥,這要?dú)w功于強(qiáng)大的字符串壓縮算法匹摇。
- 數(shù)據(jù)結(jié)構(gòu)發(fā)生變化也不會(huì)出現(xiàn)異常,包括新增字段甲葬,修改字段廊勃,修改字段類(lèi)型都沒(méi)有問(wèn)題。
- 為什么上圖說(shuō)它“毫無(wú)卵用”呢经窖,是因?yàn)樾室刃蛄谢绞降秃脦妆镀碌妫跀?shù)據(jù)量較大時(shí),字符串的壓縮和解壓縮需要消耗一定的時(shí)間画侣。
架構(gòu)
整個(gè)工程比較簡(jiǎn)單冰悠,大體上分三層,第一是api層棉钧,對(duì)外提供的接口屿脐,第二是action層,分為MemoryCache和DiskCache宪卿,第三是io層,負(fù)責(zé)數(shù)據(jù)的讀寫(xiě)万栅。Json和對(duì)象bean的轉(zhuǎn)換用的是fastJson佑钾,alibaba既然取名叫fastJson,是不是真的很快呢烦粒?有人做過(guò)實(shí)驗(yàn)休溶,當(dāng)數(shù)據(jù)比較大、比較多時(shí)扰她,fastJson的效率確實(shí)要?jiǎng)龠^(guò)其它json框架兽掰。最后當(dāng)然還有一個(gè)字符串壓縮算法。
代碼實(shí)現(xiàn)
這部分就不詳細(xì)說(shuō)了徒役,大家直接去頂部Github下載源碼即可孽尽,這里貼一堆代碼也沒(méi)什么意義。簡(jiǎn)單講一下流程:
- 支持存儲(chǔ)List忧勿、對(duì)象bean杉女、String瞻讽、int、float熏挎、double
- 所有存取操作都支持同步和異步兩種模式
- 緩存分為內(nèi)存和磁盤(pán)兩級(jí)速勇,先取內(nèi)存,內(nèi)存有值就直接返回坎拐,沒(méi)有再取磁盤(pán)
- 緩存配置目前支持內(nèi)存緩存?zhèn)€數(shù)烦磁、緩存時(shí)間,磁盤(pán)緩存?zhèn)€數(shù)哼勇、緩存時(shí)間都伪,磁盤(pán)緩存路徑
- 初始化可以使用默認(rèn)配置,也可以自定義配置
使用
1猴蹂、編譯
// 添加倉(cāng)庫(kù)
allprojects {
repositories {
jcenter()
maven { url 'https://jitpack.io' }
}
}
// 添加編譯
compile 'com.github.rjlatgithub:JsonCache:v1.2.0'
2院溺、配置
// 默認(rèn)配置
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
JsonCache.getInstance().init(getApplicationContext());
}
}
// 自定義配置
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Configuration configuration = new Configuration();
configuration.setCacheDir("http://sdcard/cache/");
configuration.setMemoryCacheCount(20);
configuration.setMemoryCacheTime(Configuration.DAY);
configuration.setDiskCacheCount(100);
configuration.setDiskCacheTime(Configuration.MONTH + Configuration.DAY * 5);
JsonCache.getInstance().init(getApplicationContext(), configuration);
}
}
3、使用
// 同步存取
User user = new User("張三", 12);
JsonCache.getInstance().saveObject("user", user);
User user = JsonCache.getInstance().loadObject("user", User.class);
// 異步存取
User user = new User("張三", 12);
JsonCache.getInstance().saveObjectAsync("user", user);
JsonCache.getInstance().loadObjectAsync("user", User.class, new ICallback<User>() {
@Override
public void onResult(User user) {
Toast.makeText(MainActivity.this, user.toString(), Toast.LENGTH_LONG).show();
}
});
優(yōu)化
- 未來(lái)優(yōu)化重點(diǎn)是效率磅轻,目前的測(cè)試結(jié)果珍逸,存、取相同對(duì)象數(shù)據(jù)聋溜,JsonCache的時(shí)間比序列化方式多兩三倍左右谆膳。
- 未來(lái)還可以增加一些實(shí)用的配置項(xiàng),目前支持的配置還比較簡(jiǎn)單撮躁。
- 數(shù)據(jù)安全性也是一個(gè)未來(lái)優(yōu)化點(diǎn)漱病,項(xiàng)目是開(kāi)源的,所以如果別人拿到了你的緩存文件把曼,就可以很輕松地獲取原始數(shù)據(jù)杨帽。