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