1. 程式人生 > >android快取框架ASimpleCache的使用 (網路請求資料並快取)

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]

  1. public static ACache get(Context ctx) {  
  2.         return get(ctx, "ACache");  
  3.     }  
  4.     public static ACache get(Context ctx, String cacheName) {  
  5.         //新建快取目錄  
  6.         ///data/data/com.yangfuhai.asimplecachedemo/cache/ACache  
  7.         File f = new File(ctx.getCacheDir(), cacheName);  
  8.         return get(f, MAX_SIZE, MAX_COUNT);  
  9.     }  
  10.     public static ACache get(File cacheDir) {  
  11.         return get(cacheDir, MAX_SIZE, MAX_COUNT);  
  12.     }  
  13.     public static ACache get(Context ctx, long max_zise, int max_count) {  
  14.         File f = new File(ctx.getCacheDir(), "ACache");  
  15.         return get(f, max_zise, max_count);  
  16.     }  
  17.     public static ACache get(File cacheDir, long max_zise, int max_count) {  
  18.         ///data/data/com.yangfuhai.asimplecachedemo/cache/ACache  
  19.         ACache manager = mInstanceMap.get(cacheDir.getAbsoluteFile() + myPid());  
  20.         if (manager == null) {  
  21.             manager = new ACache(cacheDir, max_zise, max_count);  
  22.             //{/data/data/com.yangfuhai.asimplecachedemo/cache/[email protected]}  
  23.             //{/data/data/com.yangfuhai.asimplecachedemo/cache/[email protected]}  
  24.             mInstanceMap.put(cacheDir.getAbsolutePath() + myPid(), manager);  
  25.         }  
  26.         return manager;  
  27.     }  
  28.     private static String myPid() {  
  29.         return "_" + android.os.Process.myPid();  
  30.     }  
  31.     private ACache(File cacheDir, long max_size, int max_count) {  
  32.         if (!cacheDir.exists() && !cacheDir.mkdirs()) {  
  33.             throw new RuntimeException("can't make dirs in " + cacheDir.getAbsolutePath());  
  34.         }  
  35.         mCache = new ACacheManager(cacheDir, max_size, max_count);  
  36.     }  

二,存入資料

put(String key, String value)方法寫資料到檔案

put(String key, String value)方法中的mCache.put(file)方法做了如下設定

檔案放入程式快取後,統計快取總量,總數,檔案存放到檔案map中(value值為檔案最後修改時間,便於根據設定的銷燬時間進行銷燬) 快取沒有超過限制,則增加快取總量,總數的數值 快取超過限制,則減少快取總量,總數的數值 通過removeNext方法找到最老檔案的大小

[java] 

  1. public void put(String key, String value) {  
  2.         File file = mCache.newFile(key);  
  3.         BufferedWriter out = null;  
  4.         try {  
  5.             out = new BufferedWriter(new FileWriter(file), 1024);  
  6.             out.write(value);  
  7.         } catch (IOException e) {  
  8.             e.printStackTrace();  
  9.         } finally {  
  10.             if (out != null) {  
  11.                 try {  
  12.                     out.flush();  
  13.                     out.close();  
  14.                 } catch (IOException e) {  
  15.                     e.printStackTrace();  
  16.                 }  
  17.             }  
  18.             mCache.put(file);  
  19.         }  
  20.     }  

[java] 

  1. //檔案放入程式快取後,統計快取總量,總數,檔案存放到檔案map中(value值為檔案最後修改時間,便於根據設定的銷燬時間進行銷燬)  
  2. //快取沒有超過限制,則增加快取總量,總數的數值  
  3. //快取超過限制,則減少快取總量,總數的數值  
  4. //通過removeNext方法找到最老檔案的大小  
  5. private void put(File file) {  
  6.     int curCacheCount = cacheCount.get();  
  7.     while (curCacheCount + 1 > countLimit) {  
  8.         long freedSize = removeNext();  
  9.         cacheSize.addAndGet(-freedSize);  
  10.         curCacheCount = cacheCount.addAndGet(-1);  
  11.     }  
  12.     cacheCount.addAndGet(1);  
  13.     long valueSize = calculateSize(file);  
  14.     long curCacheSize = cacheSize.get();  
  15.     while (curCacheSize + valueSize > sizeLimit) {  
  16.         long freedSize = removeNext();  
  17.         curCacheSize = cacheSize.addAndGet(-freedSize);  
  18.     }  
  19.     cacheSize.addAndGet(valueSize);  
  20.     Long currentTime = System.currentTimeMillis();  
  21.     file.setLastModified(currentTime);  
  22.     lastUsageDates.put(file, currentTime);  
  23. }  

[java] 

  1. /** 
  2.          * 移除舊的檔案(冒泡,找到最後修改時間最小的檔案) 
  3.          *  
  4.          * @return 
  5.          */  
  6.         private long removeNext() {  
  7.             if (lastUsageDates.isEmpty()) {  
  8.                 return 0;  
  9.             }  
  10.             Long oldestUsage = null;  
  11.             File mostLongUsedFile = null;  
  12.             Set<Entry<File, Long>> entries = lastUsageDates.entrySet();  
  13.             synchronized (lastUsageDates) {  
  14.                 for (Entry<File, Long> entry : entries) {  
  15.                     if (mostLongUsedFile == null) {  
  16.                         mostLongUsedFile = entry.getKey();  
  17.                         oldestUsage = entry.getValue();  
  18.                     } else {  
  19.                         Long lastValueUsage = entry.getValue();  
  20.                         if (lastValueUsage < oldestUsage) {  
  21.                             oldestUsage = lastValueUsage;  
  22.                             mostLongUsedFile = entry.getKey();  
  23.                         }  
  24.                     }  
  25.                 }  
  26.             }  
  27.             long fileSize = calculateSize(mostLongUsedFile);  
  28.             if (mostLongUsedFile.delete()) {  
  29.                 lastUsageDates.remove(mostLongUsedFile);  
  30.             }  
  31.             return fileSize;  
  32.         }  

三,獲取資料

getAsString(String key)方法從快取檔案中讀取資料,其中通過Utils.isDue(readString)方法判斷資料是否過期,是否要刪除

[java] 

  1. public String getAsString(String key) {  
  2.         ///data/data/com.yangfuhai.asimplecachedemo/cache/ACache/1727748931  
  3.         File file = mCache.get(key);  
  4.         if (!file.exists())  
  5.             return null;  
  6.         boolean removeFile = false;  
  7.         BufferedReader in = null;  
  8.         try {  
  9.             in = new BufferedReader(new FileReader(file));  
  10.             String readString = "";  
  11.             String currentLine;  
  12.             while ((currentLine = in.readLine()) != null) {  
  13.                 readString += currentLine;  
  14.             }  
  15.             if (!Utils.isDue(readString)) {  
  16.                 return Utils.clearDateInfo(readString);  
  17.             } else {  
  18.                 removeFile = true;  
  19.                 return null;  
  20.             }  
  21.         } catch (IOException e) {  
  22.             e.printStackTrace();  
  23.             return null;  
  24.         } finally {  
  25.             if (in != null) {  
  26.                 try {  
  27.                     in.close();  
  28.                 } catch (IOException e) {  
  29.                     e.printStackTrace();  
  30.                 }  
  31.             }  
  32.             if (removeFile)  
  33.                 remove(key);  
  34.         }  
  35.     }  

[java] 

  1. /** 
  2.          * 判斷快取的String資料是否到期 
  3.          *  
  4.          * @param str 
  5.          * @return true:到期了 false:還沒有到期 
  6.          */  
  7.         private static boolean isDue(String str) {  
  8.             return isDue(str.getBytes());  
  9.         }  
  10.         /** 
  11.          * 判斷快取的byte資料是否到期(到期:當前時間大於儲存時間加上儲存後的存留時間) 
  12.          *  
  13.          * @param data 
  14.          * @return true:到期了 false:還沒有到期 
  15.          */  
  16.         private static boolean isDue(byte[] data) {  
  17.             String[] strs = getDateInfoFromDate(data);  
  18.             if (strs != null && strs.length == 2) {  
  19.                 String saveTimeStr = strs[0];  
  20.                 while (saveTimeStr.startsWith("0")) {  
  21.                     saveTimeStr = saveTimeStr.substring(1, saveTimeStr.length());  
  22.                 }  
  23.                 long saveTime = Long.valueOf(saveTimeStr);  
  24.                 long deleteAfter = Long.valueOf(strs[1]);  
  25.                 if (System.currentTimeMillis() > saveTime + deleteAfter * 1000) {  
  26.                     return true;  
  27.                 }  
  28.             }  
  29.             return false;  
  30.         }  

[java] 

  1. //資料有無存留時間設定  
  2.     private static boolean hasDateInfo(byte[] data) {  
  3.         return data != null && data.length > 15 && data[13] == '-' && indexOf(data, mSeparator) > 14;  
  4.     }  
  5.        //saveDate檔案儲存時間毫秒數,deleteAfter檔案儲存後的保留時間毫秒數  
  6.     private static String[] getDateInfoFromDate(byte[] data) {  
  7.         if (hasDateInfo(data)) {  
  8.             String saveDate = new String(copyOfRange(data, 0, 13));  
  9.             String deleteAfter = new String(copyOfRange(data, 14, indexOf(data, mSeparator)));  
  10.             return new String[] { saveDate, deleteAfter };  
  11.         }  
  12.         return null;  
  13.     }