開源庫ASimpleCache使用分析

yg3n 9年前發布 | 12K 次閱讀 Android開發 移動開發 ASimpleCache

開源項目鏈接

ASimpleCache


源碼淺析

首先看下如下結構圖,思維導圖展示了ACache源碼類結構:

這里寫圖片描述

如上圖所示,ACache類的構造方法為private的,所以只能通過get方式獲取實例。默認情況下調運 ACache.get(Context);方法得到的緩存文件放置在/data/data/app-package-name/cache/路徑下,緩存的目錄默認為ACache,緩存大小和數量均由ACache中的final變量控制。

其實在獲取ACache實例時最終默認調運的實例方法是get(File cacheDir, long max_zise, int max_count);

public static ACache get(File cacheDir, long max_zise, int max_count) {
        ACache manager = mInstanceMap.get(cacheDir.getAbsoluteFile() + myPid()); if (manager == null) {
            manager = new ACache(cacheDir, max_zise, max_count);
            mInstanceMap.put(cacheDir.getAbsolutePath() + myPid(), manager);
        } return manager;
    }

第一次進來由于mInstanceMap中沒有任何map,所以manager == null。故通過ACache構造方法構造對象,構造方法如下所示。然后將實例引用存入map。

    private ACache(File cacheDir, long max_size, int max_count) {
        if (!cacheDir.exists() && !cacheDir.mkdirs()) {
            throw new RuntimeException("can't make dirs in "
                    + cacheDir.getAbsolutePath());
        }
        mCache = new ACacheManager(cacheDir, max_size, max_count);
    }

目錄不存在或者創建失敗拋出異常,否則實例化ACacheManager內部類實例。ACacheManager內部類的構造函數如下:

   private ACacheManager(File cacheDir, long sizeLimit, int countLimit) {
        this.cacheDir = cacheDir;
        this.sizeLimit = sizeLimit;
        this.countLimit = countLimit;
        cacheSize = new AtomicLong();
        cacheCount = new AtomicInteger();
        calculateCacheSizeAndCacheCount();
    }

構造函數通過calculateCacheSizeAndCacheCount();方法計算cache size和count,其中calculateCacheSizeAndCacheCount()方法如下:

private void calculateCacheSizeAndCacheCount() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            int size = 0;
            int count = 0;
            File[] cachedFiles = cacheDir.listFiles();
            if (cachedFiles != null) {
                for (File cachedFile : cachedFiles) {
                    size += calculateSize(cachedFile);
                    count += 1;
                    lastUsageDates.put(cachedFile,
                            cachedFile.lastModified());
                }
                cacheSize.set(size);
                cacheCount.set(count);
            }
        }
    }).start();
}

calculateCacheSizeAndCacheCount方法中通過開啟線程進行cache size和count的計算,放置阻塞UI線程。計算完后存入cacheSize和cacheCount,所以cacheSize和cacheCount 在內部類中定義為AtomicLong和AtomicInteger類型,也就是線程安全的,量子操作。

至此整個獲取ACache實例的過程結束。

接下來就是一堆的存取操作了。

如上結構圖,你可以通過ACache的各種public的put和get等方法進行key-value形式的緩存你想要緩存的數據類型。這里選取其中一種分析:

public void put(String key, String value, int saveTime) {
    put(key, Utils.newStringWithDateInfo(saveTime, value));
}

ACache的這個put方法可以緩存指定時間長度的key-value值。在ACache的該put方法中調運了他自身的另一個如下實現方法,其中第二個參數value傳入的是Utils.newStringWithDateInfo(saveTime, value),而newStringWithDateInfo是ACache的內部工具類的一個方法,用來拼接time為header,value為 content的字符串,然后組成新的字串返回。

    public void put(String key, String value) {
        File file = mCache.newFile(key);
        BufferedWriter out = null;
        try {
            out = new BufferedWriter(new FileWriter(file), 1024);
            out.write(value);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            mCache.put(file);
        }
    }

在put(String key, String value)方法中首先在緩存目錄下調運mCache.newFile(key)新建一個文件,新建的文件名為:File(cacheDir, key.hashCode() + “”)。然后將數據存入文件即可。

獲取過程可以直接獲取,也可以調運Utils內部類的一些方法來判斷是否緩存過期等操作。也可以刪除指定緩存或者批量操作等。

至此整個ACache的源碼分析完成,其他方法類比分析即可。

 本文由用戶 yg3n 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!