三分钟学会缓存工具DiskLruCache
DiskLruCache是一個十分好用的android緩存工具,我們可以從GitHub上下載其源碼:https://github.com/JakeWharton/DiskLruCache
DiskLruCache所有的數據都存儲在/storage/emulated/0/Android/data/應用包名/cache/XXX文件夾中(你也可以修改,但不建議這樣做,原因請繼續往下看),這個是android系統默認的應用緩存位置,如果應用被刪除,這個文件也會一起被刪除,避免應用刪除后有殘留數據的問題。同時,由于數據沒有存儲在硬盤里,所以不會影響系統性能,在sd卡里,你可以存儲任意多數據。
由于DiskLruCache是被final修飾的,因此不可以直接通過new獲得它的實例,我們使用它的open方法獲得它的一個實例:
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
open方法需要四個參數,第一個是緩存文件文件的位置,通過下面的方法可得到:
第二個參數是應用程序的版本號,要傳入版本號是因為如果應用升級緩存會被清除掉。通過下面的方法可以獲得程序的版本號:
private int getAppVersion(Context context) {try {PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);return info.versionCode;} catch (NameNotFoundException e) {e.printStackTrace();}return 1;}第三個參數表示同一個key可以對應多少個緩存文件,一般情況下我們都是傳1,這樣key和緩存文件一一對應,查找和移除都會比較方便。
第四個參數表示最大可以緩存多少字節的數據。
打開了DiskLruCache之后,我們可以看看怎么向DiskLruCache中緩存數據:
先來看看從網上down一張圖片:
這是一個簡單的聯網down圖片代碼,拿到圖片后就可以緩存到本地了,但是對于每一個存儲資源都需要有一個key,這個key要是唯一的,而且這個key最長120個字符,且只能包括a-z,0-9,下劃線以及減號,一次我們可以采用Java中的UUID來得到key,也可以使用MD5加密網址得到一個key,我這里采用md5,方法如下:
public class MD5Util {public final static String md5(String pwd) {//用于加密的字符char md5String[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9','A', 'B', 'C', 'D', 'E', 'F' };try {//使用平臺的默認字符集將此 String 編碼為 byte序列,并將結果存儲到一個新的 byte數組中byte[] btInput = pwd.getBytes();// 獲得指定摘要算法的 MessageDigest對象,此處為MD5//MessageDigest類為應用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。//信息摘要是安全的單向哈希函數,它接收任意大小的數據,并輸出固定長度的哈希值。 MessageDigest mdInst = MessageDigest.getInstance("MD5");//System.out.println(mdInst); //MD5 Message Digest from SUN, <initialized>//MessageDigest對象通過使用 update方法處理數據, 使用指定的byte數組更新摘要mdInst.update(btInput);//System.out.println(mdInst); //MD5 Message Digest from SUN, <in progress>// 摘要更新之后,通過調用digest()執行哈希計算,獲得密文byte[] md = mdInst.digest();//System.out.println(md);// 把密文轉換成十六進制的字符串形式int j = md.length;//System.out.println(j);char str[] = new char[j * 2];int k = 0;for (int i = 0; i < j; i++) { // i = 0byte byte0 = md[i]; //95str[k++] = md5String[byte0 >>> 4 & 0xf]; // 5 str[k++] = md5String[byte0 & 0xf]; // F}//返回經過加密后的字符串return new String(str);} catch (Exception e) {e.printStackTrace();return null;}} }各位看官在使用的時候記得把md5String[]中大寫的字母改為小寫,因為key中如果有大寫字母驗證會不通過。當然,你也可以修改DiskLruCache的源碼從而讓它支持大寫字母,修改的地方:
現在萬事俱備,我們來把圖片緩存起來,由于聯網是好事操作,所以要在新線程中完成,完整的方法如下:
editor.newOutputStream(0);方法有一個參數,查看源碼我們知道這個參數必須大于0并且小于valueCount,前文中valueCount我們已經設置為1了,所以這里只能取值0。這個時候打開你的緩存文件夾,/storage/emulated/0/Android/data/應用包名/cache/XXX,里邊已經有了我們緩存的數據了:
好了,數據存下來了,接下來就是讀取,每一個緩存文件都對應一個key,讀取就是根據這個key來讀取:
private void showImg() {String key = MD5Util.md5(IMGIP); try {DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);if(snapShot!=null){InputStream is = snapShot.getInputStream(0);Bitmap bitmap = BitmapFactory.decodeStream(is);im.setImageBitmap(bitmap);}} catch (IOException e) {e.printStackTrace();} }讀取的時候我們最先拿到的是一個Snapshot 對象,再根據我們之前傳入的參數0拿到緩存文件的流,最后把流轉換為圖片。
到這里大家可能就明白了,之前的editor.newOutputStream(0);方法為什么會有一個0的參數了,相當于一個標識,讀取時也傳入參數0才能讀到我們想要的數據。(加入我們的key與緩存文件不是一一對應,也就是我們一開始的open方法中傳入的不是valueCount的值不是1,那么一個key對應多個緩存文件我們要怎么區分?就是通過這種方式,有興趣的同學查看源碼就一目了然了)。
下來就是清除緩存了,看方法:
private void clearCache() {String key = MD5Util.md5(IMGIP);try {mDiskLruCache.remove(key);} catch (IOException e) {e.printStackTrace();} }根據緩存文件的key,調用remove方法,將該緩存文件移除。
下來是查看緩存大小:
像鳳凰新聞客戶端中顯示緩存大小,這個數值我們可以通過size()方法直接拿到:
大家應該看到了鳳凰新聞還有一個功能就是清除緩存,這個功能直接調用delete方法就能實現:
private void deleteAll() {/*** 這個方法用于將所有的緩存數據全部刪除* 其實只需要調用一下DiskLruCache的delete()方法就可以實現了。* 會刪除包括日志文件在內的所有文件*/try {mDiskLruCache.delete();} catch (IOException e) {e.printStackTrace();}}所有功能都完成之后,我們要記得在onDestory方法中關閉DiskLruCache。
@Overrideprotected void onDestroy() {super.onDestroy();/*** 這個方法用于將DiskLruCache關閉掉,是和open()方法對應的一個方法。* 關閉掉了之后就不能再調用DiskLruCache中任何操作緩存數據的方法,* 通常只應該在Activity的onDestroy()方法中去調用close()方法。*/try {mDiskLruCache.close();} catch (IOException e) {e.printStackTrace();}}到此,我想大家已經基本會用這個東東了吧。
最后奉上本文源碼下載地址http://pan.baidu.com/s/1kTzSHtd
版權聲明:本文為博主原創文章,未經博主允許不得轉載。若有錯誤地方,還望批評指正,不勝感激。
轉載于:https://www.cnblogs.com/lenve/p/4770527.html
總結
以上是生活随笔為你收集整理的三分钟学会缓存工具DiskLruCache的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java的原始数据类型一共就8个
- 下一篇: (算法)最长递增子序列