詳細講解Android的圖片下載框架UniversialImageLoader之磁碟快取(一)
沉浸在Android的開發世界中有一些年頭的猴子們,估計都能夠深深的體會到Android中的圖片下載、展示、快取一直是心中抹不去的痛。鄙人亦是如此。Ok,閒話不說,為了督促自己的學習,下面就逐一的挖掘Android中還算是比較牛叉的圖片處理框架UniversialImageLoader以饗讀者吧!
凡事如果過於草率必將陷入泥塘不能自拔。還是按部就班的一步一步的將這個框架給啃透。
第一個要講的是磁碟的快取的介面DiskCache
首先看一下其中的核心的介面的程式碼:
File getDirectory(); File get(String imageUri); boolean save(String imageUri, InputStream imageStream, IoUtils.CopyListener listener) throws IOException; boolean save(String imageUri, Bitmap bitmap) throws IOException; boolean remove(String imageUri); void close(); void clear();
通過以上的程式碼,發現磁碟快取的介面無非是包含這個幾方面的內容
1、獲取當前的磁碟快取的根目錄
2、通過指定的圖片的uri來獲取當前的圖片快取所對應的實體的檔案
3、將檔案流儲存到磁碟中,其中對應的引數包括:1、uri2、檔案的流 3、當前的流寫入的進度與狀態的觀察者
4、儲存Bitmap的檢視的物件到磁碟中
5、有快取圖片就必然有刪除圖圖片檔案,就如同有陰就有陽一樣,刪除圖片的引數是uri
6、關閉當前的磁碟的流,釋放操作的時候所建立的相關的資源
7、最後一個就是清除磁碟快取
第二個要講的就是實現磁碟快取的介面的類了。在這一講裡面主要是要關注3個類。分別是:BasicDiskCache、LimitedAgeDiskCache與UnLimitedAgeDiskCache。
咱們還是按照邏輯的順序來先分析一下實現磁碟快取的抽象類BasicDiskCache。
為了精簡一下,先分析其中的成員變數,相信對其中的臨時變數的講解也是可以對其整體的功能進行了解。
public static final int DEFAULT_BUFFER_SIZE = 32 * 1024; // 32 Kb public static final Bitmap.CompressFormat DEFAULT_COMPRESS_FORMAT = Bitmap.CompressFormat.PNG; public static final int DEFAULT_COMPRESS_QUALITY = 100; private static final String ERROR_ARG_NULL = " argument must be not null"; private static final String TEMP_IMAGE_POSTFIX = ".tmp"; protected final File cacheDir; protected final File reserveCacheDir; protected final FileNameGenerator fileNameGenerator; protected int bufferSize = DEFAULT_BUFFER_SIZE; protected Bitmap.CompressFormat compressFormat = DEFAULT_COMPRESS_FORMAT; protected int compressQuality = DEFAULT_COMPRESS_QUALITY;
也就是說其成員變數是:1、預設的緩衝區的尺寸 2、預設的圖片的壓縮的格式是PNG 3、預設的壓縮的質量是100 4、包括臨時的圖片檔案的快取的命名 5、快取檔案的目錄 6、快取的檔案的備胎的目錄 7、檔案的名稱命名生成器
為了讓大家更好的瞭解,咱們再拿其中的一個儲存圖片位元組流的方法來講一下吧:
@Override
public boolean save(String imageUri, InputStream imageStream, IoUtils.CopyListener listener) throws IOException {
//分析是如何儲存的
//建立一個空的檔案
File imageFile = getFile(imageUri);
//建立一個臨時的檔案
File tmpFile = new File(imageFile.getAbsolutePath() + TEMP_IMAGE_POSTFIX);
//預設當前還是沒有進行載入
boolean loaded = false;
try {
//以臨時檔案建立輸入流的物件
OutputStream os = new BufferedOutputStream(new FileOutputStream(tmpFile), bufferSize);
try {
//當前是正在拷貝對應的圖片
loaded = IoUtils.copyStream(imageStream, os, listener, bufferSize);
} finally {
IoUtils.closeSilently(os);
}
} finally {
if (loaded && !tmpFile.renameTo(imageFile)) {
loaded = false;
}
if (!loaded) {
tmpFile.delete();
}
}
return loaded;
}
從以上的程式碼中,我們知道 會建立一個臨時快取圖片的檔案,依據的引數是uri,然後利用工具類的方法將輸入流拷貝到輸出流中。
接下來需要說明的是有限的生命週期的磁碟的快取LimitedAgeDiskCache
相對於抽象類而言,當前的類的成員變數新增加了兩個:
//檔案的最大的壽命
private final long maxFileAge;
//其中的每一個檔案都對應的是一個壽命的日期
private final Map<File, Long> loadingDates = Collections.synchronizedMap(new HashMap<File, Long>());
其中的檔案的快取的最大的時間maxFileAge的單位是秒, 而對應的HashMap的作用則是快取圖片檔案所對應的載入的時間。
可以稍微的關注一下在這個類中快取檔案載入的時間的函式
private void rememberUsage(String imageUri) {
//首相建立檔案的控制代碼
File file = getFile(imageUri);
//獲取當前的時間
long currentTime = System.currentTimeMillis();
//記住修改的時間
file.setLastModified(currentTime);
//放到記憶體中
loadingDates.put(file, currentTime);
}
相對於有快取的時間限制的LimitedAgeDiskCache,UnlimitedDiskCache顯然更好理解一些,與其父類抽象類是一樣的。也就不再贅述。