ASimpleCache使用感受

一.简介

ASimpleCache只能作为一份教程,一个学习样板,不能当真把它当回事。

作者杨福海,Afinal框架也是他创造的。

可是我读ASimpleCache的900行代码时,发现各种难看,并且都是很低级的缺点。我看的代码是从github上下的,大概是2013年写的,两三年没动了。可是网上为啥那么多关于ASimpleCache的文章,大概是因为它比较短比较能说明缓存的原理吧。

二.代码缺点举例

比如拼写错误,明明是getDateInfoFromData()却写成了getDateFromDate(),虽然不太重要,但看的好难受有没有。

private static String[] getDateInfoFromDate(byte[] data) {
            if (hasDateInfo(data)) {
                String saveDate = new String(copyOfRange(data, 0, 13));
                String deleteAfter = new String(
                        copyOfRange(data, 14, indexOf(data, mSeparator)));
                return new String[]{saveDate, deleteAfter};
            }
            return null;

再比如字符串拼接问题,这个函数的作用是从文件中读取字符串,因为反复用到字符串拼接,用StringBuilder总没错吧,可是代码中用的是String,这就叫我怎能放心去用它。

public String getAsString(String key) {
        File file = mCache.get(key);
        if (!file.exists())
            return null;
        boolean removeFile = false;
        BufferedReader in = null;
        try {
            in = new BufferedReader(new FileReader(file));
            String readString = "";
            String currentLine;
            while ((currentLine = in.readLine()) != null) {
                readString += currentLine;
            }
            if (!Utils.isDue(readString)) {
                return Utils.clearDateInfo(readString);
            } else {
                removeFile = true;
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (removeFile)
                remove(key);
        }
    }

三.原理概述

缓存的当然是键值对!这个键值对不能存在内存里,否则应用程序终止之后,键值对就丢了。于是你说,那就程序关闭之前从内存里保存到磁盘不久完了。我说不行,因为程序可能非正常退出,那样键值对不就全丢了,太不稳定了。所以,既然是缓存就要把一切信息存到磁盘上去。

键就是文件名,值当然就是文件内容了。凡是缓存,必有如下几个特性:

  • 会过期,当然也可能是永远不过期,这过期时间,也应该放在磁盘上,等下次命中时,检测是否过期
  • 不重要,愿删就删,顶多费点力气重新下载

ASimpleCache把过期时间存到了文件内容中,前4个字节表示一个int,用来表示保质期秒数。

既然是文件,那就太简单了,不仅可以存字符串,还可以存二进制。这么一来,再对它封装一下,就可以直接缓存图片Bitmap和drawable,serializable和jsonObject了,他们只是一个马甲。

缓存太多了怎么办,把旧的删除。怎么算缓存太多?第一,缓存的条目(也就是键的个数)不能太多;第二,缓存的文件总大小不能太大,也就是文件夹的大小不能太大。用一个CacheManager来维护,当应用程序启动时,根据文件夹下的文件个数和文件夹大小来初始化这个CacheManager,当往缓存中put时,就先检测大小,若超过了,那就删一点再存。CacheManager还有一个作用,维护一个hashMap用于快速定位键值对,也是在应用启动时进行初始化。

存到哪里去?在android中,每一个Context都有一个getCacheDir()函数,返回的是一个文件夹,都缓存到这里去就行了。

查找时,根据key确定文件名,去cache目录下找到文件并读取全部字符串,其中这些字符串中包含着saveTime,也就是缓存的保质期。当调用get()函数获取内容时,如果发现过期了,那就不能再用它了,就把这个文件删掉,同时更改CacheManager的缓存个数及缓存大小(如果缓存太大了,就会按照最近最少使用原则删掉旧文件),如你所知,当关闭应用程序并再次启动时,需要遍历cache目录来初始化CacheManager。

原文地址:https://www.cnblogs.com/weiyinfu/p/5378942.html