android快取框架ASimpleCache的使用 (網路請求資料並快取)
官方簡介:
ASimpleCache 是一個為Android制定的 輕量級的 開源快取框架。輕量到只有一個java檔案(由十幾個類精簡而來)。
框架地址
1、它可以快取什麼東西? 普通的字串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java物件,和 byte資料。
2、它有什麼特色? 特色主要是: 1:輕,輕到只有一個JAVA檔案。 2:可配置,可以配置快取路徑,快取大小,快取數量等。 3:可以設定快取超時時間,快取超時自動失效,並被刪除。 4:支援多程序。 3、它在android中可以用在哪些場景? 1、替換SharePreference當做配置檔案 2、可以快取網路請求資料,比如oschina的android客戶端可以快取http請求的新聞內容,快取時間假設為1個小時,超時後自動失效,讓客戶端重新請求新的資料,減少客戶端流量,同時減少伺服器併發量。 3、您來說... 4、如何使用 ASimpleCache? 以下有個小的demo,希望您能喜歡:
ACache mCache = ACache.get(this); mCache.put("test_key1", "test value"); mCache.put("test_key2", "test value", 10);//儲存10秒,如果超過10秒去獲取這個key,將為null mCache.put("test_key3", "test value", 2 * ACache.TIME_DAY);//儲存兩天,如果超過兩天去獲取這個key,將為null 獲取資料
ACache mCache = ACache.get(this); String value = mCache.getAsString("test_key1");
一,首先先要建立快取
get(Context ctx, String cacheName)方法新建快取目錄
get(File cacheDir, long max_zise, int max_count)方法新建快取例項,存入例項map,key為快取目錄加上每次應用開啟的程序id
[java]
- public static ACache get(Context ctx) {
- return get(ctx, "ACache");
- }
- public static ACache get(Context ctx, String cacheName) {
- //新建快取目錄
- ///data/data/com.yangfuhai.asimplecachedemo/cache/ACache
- File f = new File(ctx.getCacheDir(), cacheName);
- return get(f, MAX_SIZE, MAX_COUNT);
- }
- public static ACache get(File cacheDir) {
- return get(cacheDir, MAX_SIZE, MAX_COUNT);
- }
- public static ACache get(Context ctx, long max_zise, int max_count) {
- File f = new File(ctx.getCacheDir(), "ACache");
- return get(f, max_zise, max_count);
- }
- public static ACache get(File cacheDir, long max_zise, int max_count) {
- ///data/data/com.yangfuhai.asimplecachedemo/cache/ACache
- ACache manager = mInstanceMap.get(cacheDir.getAbsoluteFile() + myPid());
- if (manager == null) {
- manager = new ACache(cacheDir, max_zise, max_count);
- //{/data/data/com.yangfuhai.asimplecachedemo/cache/[email protected]}
- //{/data/data/com.yangfuhai.asimplecachedemo/cache/[email protected]}
- mInstanceMap.put(cacheDir.getAbsolutePath() + myPid(), manager);
- }
- return manager;
- }
- private static String myPid() {
- return "_" + android.os.Process.myPid();
- }
- 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);
- }
二,存入資料
put(String key, String value)方法寫資料到檔案
put(String key, String value)方法中的mCache.put(file)方法做了如下設定
檔案放入程式快取後,統計快取總量,總數,檔案存放到檔案map中(value值為檔案最後修改時間,便於根據設定的銷燬時間進行銷燬) 快取沒有超過限制,則增加快取總量,總數的數值 快取超過限制,則減少快取總量,總數的數值 通過removeNext方法找到最老檔案的大小
[java]
- 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);
- }
- }
[java]
- //檔案放入程式快取後,統計快取總量,總數,檔案存放到檔案map中(value值為檔案最後修改時間,便於根據設定的銷燬時間進行銷燬)
- //快取沒有超過限制,則增加快取總量,總數的數值
- //快取超過限制,則減少快取總量,總數的數值
- //通過removeNext方法找到最老檔案的大小
- private void put(File file) {
- int curCacheCount = cacheCount.get();
- while (curCacheCount + 1 > countLimit) {
- long freedSize = removeNext();
- cacheSize.addAndGet(-freedSize);
- curCacheCount = cacheCount.addAndGet(-1);
- }
- cacheCount.addAndGet(1);
- long valueSize = calculateSize(file);
- long curCacheSize = cacheSize.get();
- 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);
- }
[java]
- /**
- * 移除舊的檔案(冒泡,找到最後修改時間最小的檔案)
- *
- * @return
- */
- private long removeNext() {
- if (lastUsageDates.isEmpty()) {
- return 0;
- }
- Long oldestUsage = null;
- File mostLongUsedFile = null;
- Set<Entry<File, Long>> entries = lastUsageDates.entrySet();
- synchronized (lastUsageDates) {
- for (Entry<File, Long> entry : entries) {
- if (mostLongUsedFile == null) {
- mostLongUsedFile = entry.getKey();
- oldestUsage = entry.getValue();
- } else {
- Long lastValueUsage = entry.getValue();
- if (lastValueUsage < oldestUsage) {
- oldestUsage = lastValueUsage;
- mostLongUsedFile = entry.getKey();
- }
- }
- }
- }
- long fileSize = calculateSize(mostLongUsedFile);
- if (mostLongUsedFile.delete()) {
- lastUsageDates.remove(mostLongUsedFile);
- }
- return fileSize;
- }
三,獲取資料
getAsString(String key)方法從快取檔案中讀取資料,其中通過Utils.isDue(readString)方法判斷資料是否過期,是否要刪除
[java]
- public String getAsString(String key) {
- ///data/data/com.yangfuhai.asimplecachedemo/cache/ACache/1727748931
- 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);
- }
- }
[java]
- /**
- * 判斷快取的String資料是否到期
- *
- * @param str
- * @return true:到期了 false:還沒有到期
- */
- private static boolean isDue(String str) {
- return isDue(str.getBytes());
- }
- /**
- * 判斷快取的byte資料是否到期(到期:當前時間大於儲存時間加上儲存後的存留時間)
- *
- * @param data
- * @return true:到期了 false:還沒有到期
- */
- private static boolean isDue(byte[] data) {
- String[] strs = getDateInfoFromDate(data);
- if (strs != null && strs.length == 2) {
- String saveTimeStr = strs[0];
- while (saveTimeStr.startsWith("0")) {
- saveTimeStr = saveTimeStr.substring(1, saveTimeStr.length());
- }
- long saveTime = Long.valueOf(saveTimeStr);
- long deleteAfter = Long.valueOf(strs[1]);
- if (System.currentTimeMillis() > saveTime + deleteAfter * 1000) {
- return true;
- }
- }
- return false;
- }
[java]
- //資料有無存留時間設定
- private static boolean hasDateInfo(byte[] data) {
- return data != null && data.length > 15 && data[13] == '-' && indexOf(data, mSeparator) > 14;
- }
- //saveDate檔案儲存時間毫秒數,deleteAfter檔案儲存後的保留時間毫秒數
- 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;
- }