詳細講解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 loadingDates = Collections.synchronizedMap(new HashMap());

其中的文件的緩存的最大的時間maxFileAge的單位是秒, 而對應的HashMap的作用則是緩存圖片文件所對應的加載的時間。

可以稍微的關註一下在這個類中緩存文件加載的時間的函數

private void rememberUsage(String imageUri) {
		//首相創建文件的句柄
		File file = getFile(imageUri);
		//獲取當前的時間
		long currentTime = System.currentTimeMillis();
		//記住修改的時間
		file.setLastModified(currentTime);
		//放到內存中
		loadingDates.put(file, currentTime);
	}

相對於有緩存的時間限制的LimitedAgeDiskCache,UnlimitedDiskCache顯然更好理解一些,與其父類抽象類是一樣的。也就不再贅述。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。