1. 程式人生 > >Android圖片載入框架最全解析(三),深入探究Glide的快取機制(筆記)

Android圖片載入框架最全解析(三),深入探究Glide的快取機制(筆記)

原文地址:Android圖片載入框架最全解析(三),深入探究Glide的快取機制

筆記:

1.Glide快取簡介

2.快取Key

EngineKey

重寫了equals()和hashCode()方法,保證只有傳入EngineKey的所有引數都相同的情況下才認為是同一個EngineKey物件

3.記憶體快取

Glide.with(this)
     .load(url)
     .skipMemoryCache(true)
     .into(imageView);

LruCache演算法(Least Recently Used)

Android高效載入大圖、多圖解決方案,有效避免程式OOM

非常容易就讓人想到LruCache演算法(Least Recently Used),也叫近期最少使用演算法。它的主要演算法原理就是把最近使用的物件用強引用儲存在LinkedHashMap中,並且把最近最少使用的物件在快取值達到預設定值之前從記憶體中移除。LruCache的用法也比較簡單
loadFromCache()方法來獲取快取圖片,如果獲取到就直接呼叫cb.onResourceReady()方法進行回撥。如果沒有獲取到,則會在第26行呼叫loadFromActiveResources()方法來獲取快取圖片,獲取到的話也直接進行回撥。只有在兩個方法都沒有獲取到快取的情況下,才會繼續向下執行,從而開啟執行緒來載入圖片。

loadFromCache()和loadFromActiveResources()。這兩個方法中一個使用的就是LruCache演算法,另一個使用的就是弱引用。

硬碟快取

Glide.with(this)
     .load(url)
     .diskCacheStrategy(DiskCacheStrategy.NONE)
     .into(imageView);

DiskCacheStrategy.NONE: 表示不快取任何內容。
DiskCacheStrategy.SOURCE: 表示只快取原始圖片。
DiskCacheStrategy.RESULT: 表示只快取轉換過後的圖片(預設選項)。
DiskCacheStrategy.ALL : 表示既快取原始圖片,也快取轉換過後的圖片。

DiskLruCache
Android DiskLruCache完全解析,硬碟快取的最佳方案

private Resource<?> decode() throws Exception {
    if (isDecodingFromCache()) {
        return decodeFromCache();
    } else {
        return decodeFromSource();
    }
}

這裡會先去呼叫DecodeJob的decodeResultFromCache()方法來獲取快取,如果獲取不到,會再呼叫decodeSourceFromCache()方法獲取快取,這兩個方法的區別其實就是DiskCacheStrategy.RESULT和DiskCacheStrategy.SOURCE這兩個引數的區別,相信不需要我再做什麼解釋吧。

高階技巧

比如之前有一位群裡的朋友就跟我說過,他們專案的圖片資源都是存放在七牛雲上面的,而七牛云為了對圖片資源進行保護,會在圖片url地址的基礎之上再加上一個token引數。也就是說,一張圖片的url地址可能會是如下格式:
http://url.com/image.jpg?token=d9caa6e02c990b0a

public class MyGlideUrl extends GlideUrl {

    private String mUrl;

    public MyGlideUrl(String url) {
        super(url);
        mUrl = url;
    }

    @Override
    public String getCacheKey() {
        return mUrl.replace(findTokenParam(), "");
    }

    private String findTokenParam() {
        String tokenParam = "";
        int tokenKeyIndex = mUrl.indexOf("?token=") >= 0 ? mUrl.indexOf("?token=") : mUrl.indexOf("&token=");
        if (tokenKeyIndex != -1) {
            int nextAndIndex = mUrl.indexOf("&", tokenKeyIndex + 1);
            if (nextAndIndex != -1) {
                tokenParam = mUrl.substring(tokenKeyIndex + 1, nextAndIndex + 1);
            } else {
                tokenParam = mUrl.substring(tokenKeyIndex);
            }
        }
        return tokenParam;
    }

}
Glide.with(this)
     .load(new MyGlideUrl(url))
     .into(imageView);