Android緩存(二)磁盤緩存DiskLruCache

DiskLruCache并不是Android系統(tǒng)內(nèi)置的緩存類,但是它得到了google的官方推薦,要使用DiskLruCache,首先需要添加依賴:

compile 'com.jakewharton:disklrucache:2.0.2'

創(chuàng)建DiskLruCache

DiskLruCache提供了一個(gè)open方法,用于磁盤緩存的創(chuàng)建。

public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)

directory表示緩存路徑,appVersion指應(yīng)用版本,valueCount指單個(gè)節(jié)點(diǎn)對(duì)應(yīng)的數(shù)據(jù)大小,設(shè)置為1就好。maxSize指緩存空間大小。

DiskLruCache會(huì)根據(jù)appVersion來識(shí)別當(dāng)前應(yīng)用的版本,如果有更新,會(huì)清除原來的數(shù)據(jù)并重建緩存,可以設(shè)置一個(gè)固定值比如1,這樣在應(yīng)用版本升級(jí)以后并不會(huì)清除原來的緩存。

appVersion應(yīng)用版本號(hào)也可以通過PackageManager來獲取,這樣能保證DiskLruCache對(duì)應(yīng)的總是新的版本:

 PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);  
        return info.versionCode;  

這里的獲取的versionCode,是在Manifest文件中定義的:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="xxx.xxx.xxxx"
          android:versionCode="1">

添加緩存數(shù)據(jù)

DiskLruCache的寫入通過Editor來完成。獲取方法如下:

DiskLruCache.Editor editor = mDiskLruCache.edit(key)

如果key對(duì)應(yīng)的緩存正在被操作(比如正在寫入),會(huì)返回null。而這里的key就是緩存中數(shù)據(jù)存儲(chǔ)的鍵值(比如url),它不允許特殊字符存在,通常我們要對(duì)它進(jìn)行轉(zhuǎn)碼:

public String hashKeyForDisk(String key) {  
    String cacheKey;  
    try {  
        final MessageDigest mDigest = MessageDigest.getInstance("MD5");  
        mDigest.update(key.getBytes());  
        cacheKey = bytesToHexString(mDigest.digest());  
    } catch (NoSuchAlgorithmException e) {  
        cacheKey = String.valueOf(key.hashCode());  
    }  
    return cacheKey;  
}  
  
private String bytesToHexString(byte[] bytes) {  
    StringBuilder sb = new StringBuilder();  
    for (int i = 0; i < bytes.length; i++) {  
        String hex = Integer.toHexString(0xFF & bytes[i]);  
        if (hex.length() == 1) {  
            sb.append('0');  
        }  
        sb.append(hex);  
    }  
    return sb.toString();  
} 

獲取到對(duì)應(yīng)的editor之后,就可以向緩存寫入數(shù)據(jù)了,寫入數(shù)據(jù)使用的是輸出流的方式,取得當(dāng)前editor的outpStream,就可以寫入數(shù)據(jù)了。

OutputStream outputStream = editor.newOutputStream(0);//獲取輸出流,參數(shù)0表示當(dāng)前key對(duì)應(yīng)的數(shù)據(jù)id,創(chuàng)建DiskLruCache時(shí)傳入的第三個(gè)參數(shù)為1,所以傳入0表示第一個(gè)

完整示例如下:
public boolean putDateToCache(DiskLruCache.Editor editor, InputStream inputStream) {

        BufferedInputStream in = null;
        BufferedOutputStream out = null;
        
        int b;
        try {
            OutputStream outputStream = editor.newOutputStream(0);
            in = new BufferedInputStream(inputStream, 4*1024);
            out = new BufferedOutputStream(outputStream, 4*1024);
            while ((b = in.read())!= -1){
                out.write(b);
            }
            editor.commit();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (out != null){
                    out.close();
                }
                if (in != null){
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
       return false;
    }

緩存內(nèi)容讀取

讀取緩存內(nèi)容使用的是get方法,它返回一個(gè)Snapshot 對(duì)象,調(diào)用snapshot的getInputStream方法就可以讀取到輸入流了。

try {  
   
    DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);  
    if (snapShot != null) {  
        InputStream is = snapShot.getInputStream(0);  
        Bitmap bitmap = BitmapFactory.decodeStream(is);  
        mImage.setImageBitmap(bitmap);  
    }  
} catch (IOException e) {  
    e.printStackTrace();  
}  

移除緩存

通常情況下,DiskLruCache會(huì)根據(jù)設(shè)置的緩存大小自動(dòng)管理數(shù)據(jù),但是如果key對(duì)應(yīng)的數(shù)據(jù)過期,可以通過remove方法手動(dòng)移除數(shù)據(jù)。

try {  
    String key = hashKeyForDisk(imageUrl);    
    mDiskLruCache.remove(key);  
} catch (IOException e) {  
    e.printStackTrace();  
}  

其他API:

  • size
    DiskLruCache的size方法返回緩存路徑下所有數(shù)據(jù)的總量,單位是byte,
  • flush
    flush用于將內(nèi)存中的操作記錄同步到日志文件(也就是journal文件)當(dāng)中。DiskLruCache能夠正常工作的前提就是要依賴于journal文件中的內(nèi)容。并不是每次寫入緩存都要調(diào)用一次flush()方法的,頻繁地調(diào)用會(huì)額外增加同步j(luò)ournal文件的時(shí)間??梢詫⒃趯懭牍ぷ魍瓿梢院笠淮涡詅lush。
  • close()
    這個(gè)方法用于將DiskLruCache關(guān)閉掉,是和open()方法對(duì)應(yīng)的一個(gè)方法。關(guān)閉掉了之后就不能再調(diào)用DiskLruCache中任何操作緩存數(shù)據(jù)的方法,通常只應(yīng)該在Activity的onDestroy()方法中去調(diào)用close()方法。
  • delete()
    這個(gè)方法用于將所有的緩存數(shù)據(jù)全部刪除,比如說網(wǎng)易新聞中的那個(gè)手動(dòng)清理緩存功能,其實(shí)只需要調(diào)用一下DiskLruCache的delete()方法就可以實(shí)現(xiàn)了。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容