三分鐘學會快取工具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 File getDiskCacheDir(Context context, String uniqueName) {
String cachePath;
//如果sd卡存在並且沒有被移除
if (Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState())
|| !Environment.isExternalStorageRemovable ()) {
cachePath = context.getExternalCacheDir().getPath();
} else {
cachePath = context.getCacheDir().getPath();
}
return new File(cachePath + File.separator + uniqueName);
}
第二個引數是應用程式的版本號,要傳入版本號是因為如果應用升級快取會被清除掉。通過下面的方法可以獲得程式的版本號:
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一張圖片:
private boolean downloadImg(final String urlStr,
final OutputStream outputStream) {
HttpURLConnection conn = null;
BufferedOutputStream out = null;
BufferedInputStream in = null;
try {
URL url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(conn.getInputStream(), 8 * 1024);
out = new BufferedOutputStream(outputStream, 8 * 1024);
int len = 0;
while ((len = in.read()) != -1) {
out.write(len);
}
return true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (conn != null)
conn.disconnect();
try {
if (out != null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (in != null)
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
這是一個簡單的聯網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 = 0
byte byte0 = md[i]; //95
str[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的原始碼從而讓它支援大寫字母,修改的地方:
現在萬事俱備,我們來把圖片快取起來,由於聯網是好事操作,所以要在新執行緒中完成,完整的方法如下:
private void cacheImg() {
new Thread(new Runnable() {
@Override
public void run() {
String key = MD5Util.md5(IMGIP);
try {
DiskLruCache.Editor editor = mDiskLruCache.edit(key);
if (editor != null) {
OutputStream out = editor.newOutputStream(0);
if (downloadImg(IMGIP, out)) {
//提交
editor.commit();
} else {
//撤銷操作
editor.abort();
}
}
/**
* 這個方法用於將記憶體中的操作記錄同步到日誌檔案(也就是journal檔案)當中。
* 這個方法非常重要,因為DiskLruCache能夠正常工作的前提就是要依賴於journal檔案中的內容。
* 並不是每次寫入快取都要呼叫一次flush()方法的,頻繁地呼叫並不會帶來任何好處,
* 只會額外增加同步journal檔案的時間。
* 比較標準的做法就是在Activity的onPause()方法中去呼叫一次flush()方法就可以了
*/
mDiskLruCache.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
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()方法直接拿到:
private void getCacheSize() {
tv.setText(mDiskLruCache.size()+"");
}
大家應該看到了鳳凰新聞還有一個功能就是清除快取,這個功能直接呼叫delete方法就能實現:
private void deleteAll() {
/**
* 這個方法用於將所有的快取資料全部刪除
* 其實只需要呼叫一下DiskLruCache的delete()方法就可以實現了。
* 會刪除包括日誌檔案在內的所有檔案
*/
try {
mDiskLruCache.delete();
} catch (IOException e) {
e.printStackTrace();
}
}
所有功能都完成之後,我們要記得在onDestory方法中關閉DiskLruCache。
@Override
protected void onDestroy() {
super.onDestroy();
/**
* 這個方法用於將DiskLruCache關閉掉,是和open()方法對應的一個方法。
* 關閉掉了之後就不能再呼叫DiskLruCache中任何操作快取資料的方法,
* 通常只應該在Activity的onDestroy()方法中去呼叫close()方法。
*/
try {
mDiskLruCache.close();
} catch (IOException e) {
e.printStackTrace();
}
}
到此,我想大家已經基本會用這個東東了吧。
相關推薦
三分鐘學會快取工具DiskLruCache
DiskLruCache所有的資料都儲存在/storage/emulated/0/Android/data/應用包名/cache/XXX資料夾中(你也可以修改,但不建議這樣做,原因請繼續往下看),這個是android系統預設的應用快取位置,如果應用被刪除,這
三分鐘學會用SpringMVC搭建最小系統(超詳細)
springmvc+mybatis dubbo+zookeeper restful redis分布式緩存 kafka 前言做 Java Web 開發的你,一定聽說過SpringMVC的大名,作為現在運用最廣泛的Java框架,它到目前為止依然保持著強大的活力和廣泛的用戶群。本文介紹如何用ecli
三分鐘學會如何在函數計算中使用 puppeteer
但是 span 排查 認證 MQ order 截圖 lan rds 摘要: 使用 puppeteer 結合函數計算,可以快速的構建彈性的服務完成各種功能,包括:生成網頁截圖或者 PDF、高級爬蟲,可以爬取大量異步渲染內容的網頁、模擬鍵盤輸入、表單自動提交、登錄網頁等,實現
三分鐘學會看大型專案的原始碼
作者:Jerish_C 來源:CSDN 原文:https://blog.csdn.net/u012999985/article/details/80877671 最近有朋友突然問我一個問題 “你怎麼把UE4引擎程式碼看的那麼深入的?” 看到問題後我還愣了一下,因為
三分鐘學會在spring boot 專案中使用RabbitMq做訊息佇列
第一步:在spring boot專案中新增RabbitMq的maven依賴 <dependency> <groupId>org.springframework.boot</groupId>
三分鐘學會用SpringMVC搭建最小系統(超詳細)_轉載
前言 做 Java Web 開發的你,一定聽說過SpringMVC的大名,作為現在運用最廣泛的Java框架,它到目前為止依然保持著強大的活力和廣泛的使用者群。 本文介紹如何用eclipse一步一步搭建SpringMVC的最小系統,所謂最小系統,就是足以使專案在SpringMVC框架下成功跑起來,並且能夠做
三分鐘學會《門面模式》
前言 只有光頭才能變強 回顧前面所寫過的設計模式: 給女朋友講解什麼是代理模式 包裝模式就是這麼簡單啦 單例模式你會幾種寫法? 工廠模式理解了沒有? 策略模式原來就這麼簡單! 無論是面試還是個人的提升,設計模式是必學的。今天來講解門面(外觀)模式~ 上一次分享了一
三分鐘學會.NET微服務之Polly
熔斷降級是一個非常重要的概念,我們先說一下什麼是熔斷降級,咱們都知道服務發現,一個有問題的伺服器沒來得急登出過一會就崩潰掉了,那麼我們的請求就有可能訪問一個已經崩潰的伺服器,那麼就會請求失敗,因為已經game over了。那麼這個問題怎麼解決呢,你一定要承認,這個問題是無法避免的。沒有什麼
java反射詳解--三分鐘學會使用java反射
本篇文章依舊採用小例子來說明,因為我始終覺的,案例驅動是最好的,要不然只看理論的話,看了也不懂,不過建議大家在看完文章之後,在回過頭去看看理論,會有更好的理解。 下面開始正文。 【案例1】通過一個物件獲得完整的包名和類名 1
三分鐘學會在ASP.NET Core MVC 中使用Cookie
一.Cookie是什麼? 我的朋友問我cookie是什麼,用來幹什麼的,可是我居然無法清楚明白簡短地向其闡述cookie,這不禁讓我陷入了沉思:為什麼我無法解釋清楚,我對學習的方法產生了懷疑!所以我們在學習一個東西的時候,一定要做到知其然知其所以然。 HTTP協議本身是無狀態的。什麼是無狀態呢,即伺
三分鐘學會.NET Core Jwt 策略授權認證
一.前言 大家好我又回來了,前幾天講過一個關於Jwt的身份驗證最簡單的案例,但是功能還是不夠強大,不適用於真正的專案,是的,在真正面對複雜而又苛刻的客戶中,我們會不知所措,就現在需要將認證授權這一塊也變的複雜而又實用起來,那在專業術語中就叫做自定義策略的API認證,本次案例執行在.NET Core 3.0
三分鐘教你學會如何將密文解碼成明文
1:準備好你的密文(將銘文轉換成密文)程式碼如下:# coding=utf-8 import base64 def encrypt(en_str): """ 加密:先對原字串作base64加密,然後將加密後的字串首尾字元對換位置,得到密文 :param en
三分鐘看懂Nginx伺服器的快取原理和機制
作者:LifeIsButA_Span 來源: http://blog.csdn.net/lifeisbuta_span/article/details/70598586 Nginx伺服器的快取原理,是在學習過程中比較重要的一個知識點,學習通透之後,對於自己的
Android之DiskLruCache(快取工具)
DiskLruCache所有的資料都儲存在/storage/emulated/0/Android/data/應用包名/cache/XXX資料夾中(你也可以修改,但不建議這樣做,原因請繼續往下看),這個是android系統預設的應用快取位置,如果應用被刪除
Android DiskLruCache快取工具封裝
介紹 Android 應用快取很常見,大多數應用都在使用DiskLruCache快取技術,也有很多人介紹過DiskLruCache,因此我在這裡就不介紹了。 DiskLruCache用起來不難,但是如果不加以封裝的話,你會遇到各種open呀各種方法的組合,總
Android基於DiskLruCache做一個數據物件的快取工具
面試的時候被問過一次,如何對資料進行快取,我答的資料庫儲存json字串。被問到可不可以不用資料庫,直接檔案快取物件。當然也是行的。之前看過郭神的部落格:用lrucache與disklrucache快取圖片的。去年也仿著敲一個圖片快取工具類點選開啟連結,今年來到新公司正好也遇到
「工具」三分鐘瞭解一款思維導圖工具:XMind Zen
一款非常實用的商業思維導圖軟體,融合藝術與創造力。致力於高效的視覺化思維,強調軟體的跨平臺使用,幫助使用者提高生產效率。 相關資訊
五分鐘學會悲觀樂觀鎖-java vs mysql vs redis三種實現
1 悲觀鎖樂觀鎖簡介 樂觀鎖( Optimistic Locking ) 相對悲觀鎖而言,樂觀鎖假設認為資料一般情況下不會造成衝突,所以在資料進行提交更新的時候,才會正式對資料的衝突與否進行檢測,如果發現衝突了,則讓返回使用者錯誤的資訊,讓使用者決定如何去做。 悲觀鎖,正如其名,它指的是對資料被外界(包括
30分鐘學會如何使用Shiro
springmvc+mybatis dubbo+zookeeper restful redis分布式緩存 shiro kafka 一、架構要學習如何使用Shiro必須先從它的架構談起,作為一款安全框架Shiro的設計相當精妙。Shiro的應用不依賴任何容器,它也可以在JavaSE下使用。但
NLTK學習筆記(三):NLTK的一些工具
ast 關註 code 值範圍 通過 自動 ive 叠代器 emma 主要總結一下簡單的工具:條件頻率分布、正則表達式、詞幹提取器和歸並器。 條件分布頻率 《自然語言學習》很多地方都用到了條件分布頻率,nltk提供了兩種常用的接口:FreqDist 和 Condit