ASimpleCache特點
ASimpleCache可以緩存什么
普通的字符串、JsonObject、JsonArray症虑、Bitmap、Drawable归薛、序列化的java對象谍憔,和 byte數(shù)據(jù)匪蝙。ASimpleCache有什么特色
(1)輕:輕到只有一個JAVA文件;
(2)可配置:可以配置緩存路徑习贫,緩存大小逛球,緩存數(shù)量等;
(3)可以設置緩存超時時間苫昌,緩存超時自動失效颤绕,并被刪除;
(4)支持多進程祟身。
ASimpleCache的疑問
-
ASimpleCache可以保存普通的字符串奥务、JsonObject、JsonArray袜硫、Bitmap氯葬、Drawable、序列化的java對象婉陷,和 byte數(shù)據(jù)帚称,那么其是如何轉(zhuǎn)化這些不同格式的數(shù)據(jù)來存儲的?
字符串可以直接通過IO庫來存儲秽澳;
將JsonObject闯睹、JsonArray調(diào)用toString()轉(zhuǎn)化為字符串,然后再存儲肝集;
byte數(shù)據(jù)可直接調(diào)用IO庫來存儲瞻坝;
Bitmap調(diào)用如下函數(shù)轉(zhuǎn)化為byte[]來存儲:
private static byte[] Bitmap2Bytes(Bitmap bm) {
if (bm == null) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
return baos.toByteArray();
}
Drawable通過調(diào)用如下函數(shù)蛛壳,轉(zhuǎn)換為Bitmap來存儲:
private static Bitmap drawable2Bitmap(Drawable drawable) {
if (drawable == null) {
return null;
}
// 取 drawable 的長寬
int w = drawable.getIntrinsicWidth();
int h = drawable.getIntrinsicHeight();
// 取 drawable 的顏色格式
Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565;
// 建立對應 bitmap
Bitmap bitmap = Bitmap.createBitmap(w, h, config);
// 建立對應 bitmap 的畫布
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, w, h);
// 把 drawable 內(nèi)容畫到畫布中
drawable.draw(canvas);
return bitmap;
}
序列化的JAVA對象可直接通過如下函數(shù)存儲:
public void put(String key, Serializable value, int saveTime) {
ByteArrayOutputStream baos = null;
ObjectOutputStream oos = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(value);
byte[] data = baos.toByteArray();
if (saveTime != -1) {
put(key, data, saveTime);
} else {
put(key, data);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
oos.close();
} catch (IOException e) {
}
}
}
- 對超過緩存時間的文件是如何處理的杏瞻?
a、保存創(chuàng)建時間
在put時衙荐,將文件創(chuàng)建時間和想要保存的數(shù)據(jù)捞挥,通過如下函數(shù),
// saveTime保存時間忧吟,value需要保存的值砌函;
Utils.newByteArrayWithDateInfo(saveTime, value)
打包生成二進制數(shù)據(jù),然后調(diào)用
void put(String key, byte[] value)
保存數(shù)據(jù)即可溜族;
b讹俊、讀取創(chuàng)建時間并判斷是否過期
在調(diào)用get(String key)來獲取保存的數(shù)據(jù)時,調(diào)用ASimpleCacheUtil.isDue(byte[] data) 來獲取創(chuàng)建時間煌抒,然后加上緩存時間仍劈,并與當前時間對比,如超過緩存時間寡壮,則返回為null贩疙,否則讹弯,返回該數(shù)據(jù)。
與料想中的不一樣这溅,設置緩存時間组民,并不會導致該文件過了緩存時間就被刪除。
-
如何保持ASimpleCache的緩存大斜ァ臭胜?
在ASimpleCache.ACacheManager內(nèi)部維護一個map: Map<File, Long> lastUsageDates ,在每次get()或put()操作時癞尚,都將更新該File對應的value值為當前時間庇楞。
在每次進行put操作時,會進行如下操作:
private void put(File file) {
int curCacheCount = cacheCount.get();
//一直刪除最少用到的文件否纬,直到存儲的文件數(shù)目小于限制數(shù)目吕晌;
while (curCacheCount + 1 > countLimit) {
long freedSize = removeNext();
//每調(diào)用removeNext()一次,將刪除lastUsageDate值最小的那個文件
cacheSize.addAndGet(-freedSize);
curCacheCount = cacheCount.addAndGet(-1);
}
cacheCount.addAndGet(1);
long valueSize = calculateSize(file);
long curCacheSize = cacheSize.get();
//一直刪除“最少用到的文件”临燃,直到存儲的文件size小于限制的文件size睛驳;
while (curCacheSize + valueSize > sizeLimit) {
long freedSize = removeNext();
curCacheSize = cacheSize.addAndGet(-freedSize);
}
cacheSize.addAndGet(valueSize);
Long currentTime = System.currentTimeMillis();
file.setLastModified(currentTime);
lastUsageDates.put(file, currentTime);
}