天天看點

Android開源項目 異步圖檔緩存庫 Universal-Image-Loader

在Android開發中,網絡IO等耗時操作應獨立于UI線程,對于需要使用大量網絡圖檔的應用來說,能夠異步下載下傳并緩存圖檔的子產品顯得非常重要。

如名,異步緩存系統的兩大特性是:

1.異步下載下傳資源

2.緩存系統

基本思路:要實作一個最簡單的異步緩存功能,可以開啟一個Thread,通過Http下載下傳圖檔,用HashMap緩存圖檔即可。

建立緩存時可以使用記憶體緩存和磁盤緩存,擷取資料時先從記憶體緩存讀取,如果沒有資料則從磁盤緩存讀取,再沒有則從網絡下載下傳,下載下傳完後記得寫入磁盤緩存,記憶體緩存。

本文要介紹的 Universal-Image-Loader (以下簡稱UIL)也是類似思路,但功能更加強大,其建立了一套架構,友善擴充和配置,使用起來更為靈活。

UIL是GitHub上的開源項目,位址:https://github.com/nostra13/Android-Universal-Image-Loader

這裡提供了完整的源碼和示例,初次使用請閱讀ReadMe文檔了解基本情況。

使用方法:

1.Android工程導入庫檔案 universal-image-loader-xxx-with-sources.jar(在下載下傳的downloads目錄)

2.設定權限

<manifest>

<uses-permission android:name="android.permission.INTERNET" />

<!-- 如果要緩存圖檔到磁盤需要設定 -->

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

...

<application android:name="MyApplication">

...

</application>

</manifest>

3.編寫代碼

隻需要三個步驟:

  (1) 配置選項

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())

...

.build();

  (2)初始化ImageLoader

ImageLoader.getInstance().init(config);

  (3)顯示圖檔

ImageLoader.getInstance().displayImage(imageUrl, imageView); 

ImageLoader.getInstance().displayImage(imageUrl, listener); //通過listener傳遞ImageView對象

其中1,2兩步初始化過程可以在繼承Application的類中完成,第3步可以在Activity或Adapter等需要顯示圖檔的類中完成

ImageLoader實作了displayImage和loadImage的多個不同版本的方法,具體可參考源碼。

支援的URI類型

String imageUri = "http://site.com/image.png"; // 網絡資源

String imageUri = "file:///mnt/sdcard/image.png"; // SD card 資源

String imageUri = "content://media/external/audio/albumart/13"; // content provider 資源

String imageUri = "assets://image.png"; // assets 資源

String imageUri = "drawable://" + R.drawable.image; // drawables 資源(針對非.9.png圖檔)

注:為提高效率,當使用"drawable://格式uri"時,盡量使用本地方法ImageView.setImageResource(...)

配置選項:

該項目包含2個配置選項的類:

1.ImageLoaderConfiguration 是全局配置,建立ImageLoader時使用

2.DisplayImageOptions 是局部配置,每次加載或顯示圖檔時都可指定顯示選項

ImageLoaderConfiguration 示例

//這裡隻是列出各種情況的例子,在設定自己的選項時不要完全拷貝這裡的代碼

//ImageLoaderConfiguration類中有個方法會判斷如果某項沒有設定,則建立預設的選項

File cacheDir = StorageUtils.getCacheDirectory(context);

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)

.memoryCacheExtraOptions(480, 800) //解析圖檔時使用的最大尺寸,預設為裝置螢幕寬高

.discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null) //從網絡下載下傳圖檔後儲存到磁盤時使用的圖檔尺寸及壓縮方法,如果不設定則儲存原始圖檔

.taskExecutor(...)  //加載顯示圖檔任務,預設建立一個以FIFO(先進先出)方式排程線程池的任務

.taskExecutorForCachedImages(...)  //顯示圖檔任務(隻針對已緩存到磁盤的圖檔),預設建立一個以FIFO(先進先出)方式排程線程池的任務

.threadPoolSize(3) // 線程池大小,這裡是預設值(注意不要設太大,否則會有OOM問題)

.threadPriority(Thread.NORM_PRIORITY - 1) // 線程優先級,這裡是預設值

.tasksProcessingOrder(QueueProcessingType.FIFO) // 線程排程方式,這裡是預設值

.denyCacheImageMultipleSizesInMemory()  //關閉記憶體緩存同一張圖檔不同情況尺寸,對于同一張圖檔,當有不同尺寸緩存時後面尺寸會覆寫前面的尺寸

.memoryCache(new LruMemoryCache(2 * 1024 * 1024))   //設定記憶體緩存,預設會建立緩存大小為應用可用記憶體總大小1/8的LruMemoryCache

.memoryCacheSize(2 * 1024 * 1024)  //設定記憶體緩存大小

.memoryCacheSizePercentage(13) // 設定記憶體緩存大小在應用可用總記憶體大小的比例

.discCache(new UnlimitedDiscCache(cacheDir)) // 磁盤緩存,這裡是預設方式

.discCacheSize(50 * 1024 * 1024)  //磁盤緩存大小

.discCacheFileCount(100)   //磁盤緩存檔案數量(如果使用FileCountLimitedDiscCache)

.discCacheFileNameGenerator(new HashCodeFileNameGenerator()) // 磁盤緩存時檔案命名方法,這裡是預設值。另外該庫還提供了MD5方式命名。

.imageDownloader(new BaseImageDownloader(context)) // 圖檔下載下傳器,這裡是預設方式

.imageDecoder(new BaseImageDecoder()) // 圖檔解碼器,這裡為預設方式

.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // 圖檔顯示器,這裡是預設方式

.writeDebugLogs()  //是否列印調試log

.build();

DisplayImageOptions 示例:

//這裡隻是列出各種情況的例子,在設定自己的選項時不要完全拷貝這裡的代碼

DisplayImageOptions options = new DisplayImageOptions.Builder()

.showImageOnLoading(R.drawable.ic_stub) // 加載圖檔時顯示的圖示

.showImageForEmptyUri(R.drawable.ic_empty) // uri為空時顯示的圖示

.showImageOnFail(R.drawable.ic_error) // 下載下傳圖檔失敗時顯示的圖示

.resetViewBeforeLoading(false)  // 加載圖檔前是否清空ImageView,預設為false

.delayBeforeLoading(1000) //加載圖檔前延遲時間,預設為0

.cacheInMemory(false) // 是否啟用記憶體緩存,預設為false

.cacheOnDisc(false) // 是否啟用磁盤緩存,預設為false

.preProcessor(...)  //圖檔處理函數,在圖檔緩存到記憶體之前運作

.postProcessor(...) //圖檔處理函數,在圖檔緩存到記憶體之後但顯示圖檔之前運作

.extraForDownloader(...)  //下載下傳圖檔時額外資訊

.considerExifParams(false) // 解析圖檔時是否考慮JPEG圖檔的Exif資訊,預設為false

.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // 解析圖檔時縮放因子,這裡是預設值

.bitmapConfig(Bitmap.Config.ARGB_8888) // 解析圖檔時采用的色彩格式,這裡是預設值

.decodingOptions(...)  //解析圖檔時的option參數,該參數會覆寫上面的bitmapConfig中的參數,但其中的inSampleSize會被忽略,其采用imageScaleType設定的值

.displayer(new SimpleBitmapDisplayer()) // 圖檔顯示器,這裡是預設方式

.handler(new Handler()) // UI線程handler,用于綁定ImageView和Bitmap

.build();

目錄結構

Android開源項目 異步圖檔緩存庫 Universal-Image-Loader

ImageLoaderEngine: 控制并發任務

LoadAndDisplayImageTask:加載和顯示圖檔任務

xxxImageDownloader: 負責從網絡,檔案等擷取圖檔資料流

xxxImageDecoder:解析圖檔

xxxBitmapDisplayer: 負責顯示圖檔效果

  SimpleBitmapDisplayer:直接顯示圖檔

  FadeInBitmapDisplayer:淡入淡出效果

  RoundedBitmapDisplayer:顯示圓角

  RoundedVignetteBitmapDisplayer:圓角帶光暈效果

Cache: 緩存

  MemoryCache: 記憶體緩存,通常使用元素為<String,Bitmap> 的Map來維護緩存内容

WeakMemoryCache:弱引用緩存,簡單地對每個bitmap做弱引用

FuzzyKeyMemoryCache:可以傳入比較規則,将不同的key視作相同,這樣Map中新加元素時會将原來對應key的value覆寫

LruMemoryCache:當緩存容量超過最大值時,删除最近最少使用的對象

LRULimitedMemoryCache:當緩存容量超過最大值時,删除最近最少使用的對象

FIFOLimitedMemoryCache:當緩存容量超過最大值時,删除最先放入隊列的對象

LargestLimitedMemoryCache:當緩存容量超過最大值時,删除目前最大的對象

LimitedAgeMemoryCache:當緩存容量超過最大值時,删除存活時間最長的對象

UsingFreqLimitedMemoryCache:當緩存容量超過最大值時,删除最不常使用的對象

  DiscCache: 磁盤緩存,使用元素為<String,Key>的Map來維護緩存内容

UnlimitedDiscCache:無限制

LimitedAgeDiscCache:當緩存對象緩存時間超過設定值時,将會被删除

TotalSizeLimitedDiscCache:當緩存容量超過最大值時,删除最不活躍的對象(上一次使用時間最早的對象)

FileCountLimitedDiscCache:當緩存檔案數量超過最大值時,删除最不活躍的對象(上一次使用時間最早的對象)

緩存類圖:

Android開源項目 異步圖檔緩存庫 Universal-Image-Loader
Android開源項目 異步圖檔緩存庫 Universal-Image-Loader

ImageLoaderEngine 中包含三個Executor成員對象,每個都帶有線程池,其中一個Executor作為排程者用于管理另外兩個Executor

另兩個Executor一個用于下載下傳網絡圖檔,另一個專門處理已經在磁盤緩存過的圖檔。

Android開源項目 異步圖檔緩存庫 Universal-Image-Loader

整體流程圖:

Android開源項目 異步圖檔緩存庫 Universal-Image-Loader

以上是關于UIL異步緩存架構的大體介紹,源碼這裡就不貼出來了,感興趣的讀者可以自己研究一下。

網上有很多詳細介紹的,這裡推薦幾個:

Android 開源架構Universal-Image-Loader完全解析:

http://blog.csdn.net/xiaanming/article/details/26810303

Android 架構練成 教你打造高效的圖檔加載架構 :

http://blog.csdn.net/lmj623565791/article/details/41874561