ASimpleCache的三个疑问

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: Map lastUsageDates ,在每次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);
        }

你可能感兴趣的:(ASimpleCache的三个疑问)