ASimpleCache特点
ASimpleCache可以缓存什么
普通的字符串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java对象,和 byte数据。ASimpleCache有什么特色
(1)轻:轻到只有一个JAVA文件;
(2)可配置:可以配置缓存路径,缓存大小,缓存数量等;
(3)可以设置缓存超时时间,缓存超时自动失效,并被删除;
(4)支持多进程。
ASimpleCache的疑问
- ASimpleCache可以保存普通的字符串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java对象,和 byte数据,那么其是如何转化这些不同格式的数据来存储的?
字符串可以直接通过IO库来存储;
将JsonObject、JsonArray调用toString()转化为字符串,然后再存储;
byte数据可直接调用IO库来存储;
Bitmap调用如下函数转化为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通过调用如下函数,转换为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 内容画到画布中
drawable.draw(canvas);
return bitmap;
}
序列化的JAVA对象可直接通过如下函数存储:
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、保存创建时间
在put时,将文件创建时间和想要保存的数据,通过如下函数,
// saveTime保存时间,value需要保存的值;
Utils.newByteArrayWithDateInfo(saveTime, value)
打包生成二进制数据,然后调用
void put(String key, byte[] value)
保存数据即可;
b、读取创建时间并判断是否过期
在调用get(String key)来获取保存的数据时,调用ASimpleCacheUtil.isDue(byte[] data) 来获取创建时间,然后加上缓存时间,并与当前时间对比,如超过缓存时间,则返回为null,否则,返回该数据。
与料想中的不一样,设置缓存时间,并不会导致该文件过了缓存时间就被删除。
- 如何保持ASimpleCache的缓存大小?
在ASimpleCache.ACacheManager内部维护一个map: MaplastUsageDates ,在每次get()或put()操作时,都将更新该File对应的value值为当前时间。
在每次进行put操作时,会进行如下操作:
private void put(File file) {
int curCacheCount = cacheCount.get();
//一直删除最少用到的文件,直到存储的文件数目小于限制数目;
while (curCacheCount + 1 > countLimit) {
long freedSize = removeNext();
//每调用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);
}