1. 程式人生 > >android universal image loader 緩衝原理詳解

android universal image loader 緩衝原理詳解

1. 功能介紹

1.1 Android Universal Image Loader

Android Universal Image Loader 是一個強大的、可高度定製的圖片快取,本文簡稱為UIL
簡單的說 UIL 就做了一件事——獲取圖片並顯示在相應的控制元件上。

1.2 基本使用

1.2.1 初始化

新增完依賴後在ApplicationActivity中初始化ImageLoader,如下:

public class YourApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(this)
            // 新增你的配置需求
            .build();
        ImageLoader.getInstance().init(configuration);
    }
}

其中 configuration 表示ImageLoader的配置資訊,可包括圖片最大尺寸、執行緒池、快取、下載器、解碼器等等。

1.2.2 Manifest 配置
<manifest>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <application
        android:name=".YourApplication"
        …… >
        ……
    </application>
</manifest>

新增網路許可權。如果允許磁碟快取,需要新增寫外設的許可權。

1.2.3 下載顯示圖片

下載圖片,解析為 Bitmap 並在 ImageView 中顯示。

imageLoader.displayImage(imageUri, imageView);

下載圖片,解析為 Bitmap 傳遞給回撥介面。

imageLoader.loadImage(imageUri, new SimpleImageLoadingListener() {
    @Override
    public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
        // 圖片處理
    }
});

以上是簡單使用,更復雜 API 見本文詳細設計

1.3 特點

  • 可配置度高。支援任務執行緒池、下載器、解碼器、記憶體及磁碟快取、顯示選項等等的配置。
  • 包含記憶體快取和磁碟快取兩級快取。
  • 支援多執行緒,支援非同步和同步載入。
  • 支援多種快取演算法、下載進度監聽、ListView 圖片錯亂解決等。

2. 總體設計

2.1. 總體設計圖

總體設計圖
上面是 UIL 的總體設計圖。整個庫分為ImageLoaderEngineCacheImageDownloaderImageDecoderBitmapDisplayerBitmapProcessor五大模組,其中Cache分為MemoryCacheDiskCache兩部分。

簡單的講就是ImageLoader收到載入及顯示圖片的任務,並將它交給ImageLoaderEngineImageLoaderEngine分發任務到具體執行緒池去執行,任務通過CacheImageDownloader獲取圖片,中間可能經過BitmapProcessorImageDecoder處理,最終轉換為Bitmap交給BitmapDisplayerImageAware中顯示。

2.2. UIL 中的概念

簡單介紹一些概念,在4. 詳細設計中會仔細介紹。
ImageLoaderEngine:任務分發器,負責分發LoadAndDisplayImageTaskProcessAndDisplayImageTask給具體的執行緒池去執行,本文中也稱其為engine,具體參考4.2.6 ImageLoaderEngine.java

ImageAware:顯示圖片的物件,可以是ImageView等,具體參考4.2.9 ImageAware.java

ImageDownloader:圖片下載器,負責從圖片的各個來源獲取輸入流, 具體參考4.2.22 ImageDownloader.java

Cache:圖片快取,分為MemoryCacheDiskCache兩部分。

MemoryCache:記憶體圖片快取,可向記憶體快取快取圖片或從記憶體快取讀取圖片,具體參考4.2.24 MemoryCache.java

DiskCache:本地圖片快取,可向本地磁碟快取儲存圖片或從本地磁碟讀取圖片,具體參考4.2.38 DiskCache.java

ImageDecoder:圖片解碼器,負責將圖片輸入流InputStream轉換為Bitmap物件, 具體參考4.2.53 ImageDecoder.java

BitmapProcessor:圖片處理器,負責從快取讀取或寫入前對圖片進行處理。具體參考4.2.61 BitmapProcessor.java

BitmapDisplayer:Bitmap物件顯示在相應的控制元件ImageAware上, 具體參考4.2.56 BitmapDisplayer.java

LoadAndDisplayImageTask:用於載入並顯示圖片的任務, 具體參考4.2.20 LoadAndDisplayImageTask.java

ProcessAndDisplayImageTask:用於處理並顯示圖片的任務, 具體參考4.2.19 ProcessAndDisplayImageTask.java

DisplayBitmapTask:用於顯示圖片的任務, 具體參考4.2.18 DisplayBitmapTask.java

3. 流程圖


上圖為圖片載入及顯示流程圖,在uil庫中給出,這裡用中文重新畫出。

4. 詳細設計

4.1 類關係圖

4.2 核心類功能介紹

4.2.1 ImageLoader.java

圖片載入器,對外的主要 API,採取了單例模式,用於圖片的載入和顯示。

主要函式:

(1). getInstance()

得到ImageLoader的單例。通過雙層是否為 null 判斷提高效能。

(2). init(ImageLoaderConfiguration configuration)

初始化配置引數,引數configurationImageLoader的配置資訊,包括圖片最大尺寸、任務執行緒池、磁碟快取、下載器、解碼器等等。
實現中會初始化ImageLoaderEngine engine屬性,該屬性為任務分發器。

(3). displayImage(String uri, ImageAware imageAware, DisplayImageOptions options, ImageLoadingListener listener, ImageLoadingProgressListener progressListener)

載入並顯示圖片或載入並執行回撥介面。ImageLoader 載入圖片主要分為三類介面:

  • displayImage(…) 表示非同步載入並顯示圖片到對應的ImageAware上。
  • loadImage(…) 表示非同步載入圖片並執行回撥介面。
  • loadImageSync(…) 表示同步載入圖片。

以上三類介面最終都會呼叫到這個函式進行圖片載入。函式引數解釋如下:
uri: 圖片的 uri。uri 支援多種來源的圖片,包括 http、https、file、content、assets、drawable 及自定義,具體介紹可見ImageDownloader
imageAware: 一個介面,表示需要載入圖片的物件,可包裝 View。
options: 圖片顯示的配置項。比如載入前、載入中、載入失敗應該顯示的佔位圖片,圖片是否需要在磁碟快取,是否需要在記憶體快取等。
listener: 圖片載入各種時刻的回撥介面,包括開始載入、載入失敗、載入成功、取消載入四個時刻的回撥函式。
progressListener: 圖片載入進度的回撥介面。

函式流程圖如下:
ImageLoader Display Image Flow Chart

4.2.2 ImageLoaderConfiguration.java

ImageLoader的配置資訊,包括圖片最大尺寸、執行緒池、快取、下載器、解碼器等等。

主要屬性:

(1). Resources resources

程式本地資源訪問器,用於載入DisplayImageOptions中設定的一些 App 中圖片資源。

(2). int maxImageWidthForMemoryCache

記憶體快取的圖片最大寬度。

(3). int maxImageHeightForMemoryCache

記憶體快取的圖片最大高度。

(4). int maxImageWidthForDiskCache

磁碟快取的圖片最大寬度。

(5). int maxImageHeightForDiskCache

磁碟快取的圖片最大高度。

(6). BitmapProcessor processorForDiskCache

圖片處理器,用於處理從磁碟快取中讀取到的圖片。

(7). Executor taskExecutor

ImageLoaderEngine中用於執行從源獲取圖片任務的 Executor。

(18). Executor taskExecutorForCachedImages

ImageLoaderEngine中用於執行從快取獲取圖片任務的 Executor。

(19). boolean customExecutor

使用者是否自定義了上面的 taskExecutor。

(20). boolean customExecutorForCachedImages

使用者是否自定義了上面的 taskExecutorForCachedImages。

(21). int threadPoolSize

上面兩個預設執行緒池的核心池大小,即最大併發數。

(22). int threadPriority

上面兩個預設執行緒池的執行緒優先順序。

(23). QueueProcessingType tasksProcessingType

上面兩個預設執行緒池的執行緒佇列型別。目前只有 FIFO, LIFO 兩種可供選擇。

(24). MemoryCache memoryCache

圖片記憶體快取。

(25). DiskCache diskCache

圖片磁碟快取,一般放在 SD 卡。

(26). ImageDownloader downloader

圖片下載器。

(27). ImageDecoder decoder

圖片解碼器,內部可使用我們常用的BitmapFactory.decode(…)將圖片資源解碼成Bitmap物件。

(28). DisplayImageOptions defaultDisplayImageOptions

圖片顯示的配置項。比如載入前、載入中、載入失敗應該顯示的佔位圖片,圖片是否需要在磁碟快取,是否需要在記憶體快取等。

(29). ImageDownloader networkDeniedDownloader

不允許訪問網路的圖片下載器。

(30). ImageDownloader slowNetworkDownloader

慢網路情況下的圖片下載器。

4.2.3 ImageLoaderConfiguration.Builder.java 靜態內部類

Builder 模式,用於構造引數繁多的ImageLoaderConfiguration
其屬性與ImageLoaderConfiguration類似,函式多是屬性設定函式。

主要函式及含義:

(1). build()

按照配置,生成 ImageLoaderConfiguration。程式碼如下:

public ImageLoaderConfiguration build() {
    initEmptyFieldsWithDefaultValues();
    return new ImageLoaderConfiguration(this);
}
(2). initEmptyFieldsWithDefaultValues()

初始化值為null的屬性。若使用者沒有配置相關項,UIL 會通過呼叫DefaultConfigurationFactory中的函式返回一個預設值當配置。
taskExecutorForCachedImagestaskExecutorImageLoaderEnginetaskDistributor的預設值如下:

parameters taskDistributor taskExecutorForCachedImages/taskExecutor
corePoolSize 0 3
maximumPoolSize Integer.MAX_VALUE 3
keepAliveTime 60 0
unit SECONDS MILLISECONDS
workQueue SynchronousQueue LIFOLinkedBlockingDeque / LinkedBlockingQueue
priority 5 3

diskCacheFileNameGenerator預設值為HashCodeFileNameGenerator
memoryCache預設值為LruMemoryCache。如果記憶體快取不允許快取一張圖片的多個尺寸,則用FuzzyKeyMemoryCache做封裝,同一個圖片新的尺寸會覆蓋快取中該圖片老的尺寸。
diskCache預設值與diskCacheSizediskCacheFileCount值有關,如果他們有一個大於 0,則預設為LruDiskCache,否則使用無大小限制的UnlimitedDiskCache
downloader預設值為BaseImageDownloader
decoder預設值為BaseImageDecoder
詳細及其他屬性預設值請到DefaultConfigurationFactory中檢視。

(3). denyCacheImageMultipleSizesInMemory()

設定記憶體快取不允許快取一張圖片的多個尺寸,預設允許。
後面會講到 View 的 getWidth() 在初始化前後的不同值與這個設定的關係。

(4). diskCacheSize(int maxCacheSize)

設定磁碟快取的最大位元組數,如果大於 0 或者下面的maxFileCount大於 0,預設的DiskCache會用LruDiskCache,否則使用無大小限制的UnlimitedDiskCache

(5). diskCacheFileCount(int maxFileCount)

設定磁碟快取資料夾下最大檔案數,如果大於 0 或者上面的maxCacheSize大於 0,預設的DiskCache會用LruDiskCache,否則使用無大小限制的UnlimitedDiskCache

4.2.4 ImageLoaderConfiguration.NetworkDeniedImageDownloader.java 靜態內部類

不允許訪問網路的圖片下載器,實現了ImageDownloader介面。
實現也比較簡單,包裝一個ImageDownloader物件,通過在 getStream(…) 函式中禁止 Http 和 Https Scheme 禁止網路訪問,如下:

@Override
public InputStream getStream(String imageUri, Object extra) throws IOException {
    switch (Scheme.ofUri(imageUri)) {
        case HTTP:
        case HTTPS:
            throw new IllegalStateException();
        default:
            return wrappedDownloader.getStream(imageUri, extra);
    }
}
4.2.5 ImageLoaderConfiguration.SlowNetworkImageDownloader.java 靜態內部類

慢網路情況下的圖片下載器,實現了ImageDownloader介面。
通過包裝一個ImageDownloader物件實現,在 getStream(…) 函式中當 Scheme 為 Http 和 Https 時,用FlushedInputStream代替InputStream處理慢網路情況,具體見後面FlushedInputStream的介紹。

4.2.6 ImageLoaderEngine.java

LoadAndDisplayImageTaskProcessAndDisplayImageTask任務分發器,負責分發任務給具體的執行緒池。

主要屬性:

(1). ImageLoaderConfiguration configuration

ImageLoader的配置資訊,可包括圖片最大尺寸、執行緒池、快取、下載器、解碼器等等。

(2). Executor taskExecutor

用於執行從源獲取圖片任務的 Executor,為configuration中的 taskExecutor,如果為null,則會呼叫DefaultConfigurationFactory.createExecutor(…)根據配置返回一個預設的執行緒池。

(3). Executor taskExecutorForCachedImages

用於執行從快取獲取圖片任務的 Executor,為configuration中的 taskExecutorForCachedImages,如果為null,則會呼叫DefaultConfigurationFactory.createExecutor(…)根據配置返回一個預設的執行緒池。

(4). Executor taskDistributor

任務分發執行緒池,任務指LoadAndDisplayImageTaskProcessAndDisplayImageTask,因為只需要分發給上面的兩個 Executor 去執行任務,不存在較耗時或阻塞操作,所以用無併發數(Int 最大值)限制的執行緒池即可。

(5). Map cacheKeysForImageAwares

ImageAware與記憶體快取 key 對應的 map,key 為ImageAware的 id,value 為記憶體快取的 key。

(6). Map uriLocks

圖片正在載入的重入鎖 map,key 為圖片的 uri,value 為標識其正在載入的重入鎖。

(7). AtomicBoolean paused

是否被暫停。如果為true,則所有新的載入或顯示任務都會等待直到取消暫停(為false)。

(8). AtomicBoolean networkDenied

是否不允許訪問網路,如果為true,通過ImageLoadingListener.onLoadingFailed(…)獲取圖片,則所有不在快取中需要網路訪問的請求都會失敗,返回失敗原因為網路訪問被禁止

(9). AtomicBoolean slowNetwork

是否是慢網路情況,如果為true,則自動呼叫SlowNetworkImageDownloader下載圖片。

(10). Object pauseLock

暫停的等待鎖,可在engine被暫停後呼叫這個鎖等待。

主要函式:

(1). void submit(final LoadAndDisplayImageTask task)

新增一個LoadAndDisplayImageTask。直接用taskDistributor執行一個 Runnable,在 Runnable 內部根據圖片是否被磁碟快取過確定使用taskExecutorForCachedImages還是taskExecutor執行該 task。

(2). void submit(ProcessAndDisplayImageTask task)

新增一個ProcessAndDisplayImageTask。直接用taskExecutorForCachedImages執行該 task。

(3). void pause()

暫停圖片載入任務。所有新的載入或顯示任務都會等待直到取消暫停(為false)。

(4). void resume()

繼續圖片載入任務。

(5). stop()

暫停所有載入和顯示圖片任務並清除這裡的內部屬性值。

(6). fireCallback(Runnable r)

taskDistributor立即執行某個任務。

(7). getLockForUri(String uri)

得到某個 uri 的重入鎖,如果不存在則新建。

(8). createTaskExecutor()

呼叫DefaultConfigurationFactory.createExecutor(…)建立一個執行緒池。

(9). getLoadingUriForView(ImageAware imageAware)

得到某個imageAware正在載入的圖片 uri。

(10). prepareDisplayTaskFor(ImageAware imageAware, String memoryCacheKey)

準備開始一個Task。向cacheKeysForImageAwares中插入ImageAware的 id 和圖片在記憶體快取中的 key。

(11). void cancelDisplayTaskFor(ImageAware imageAware)

取消一個顯示任務。從cacheKeysForImageAwares中刪除ImageAware對應元素。

(12). denyNetworkDownloads(boolean denyNetworkDownloads)

設定是否不允許網路訪問。

(13). handleSlowNetwork(boolean handleSlowNetwork)

設定是否慢網路情況。

4.2.7 DefaultConfigurationFactory.java

ImageLoaderConfigurationImageLoaderEngine提供一些預設配置。

主要函式:

(1). createExecutor(int threadPoolSize, int threadPriority, QueueProcessingType tasksProcessingType)

建立執行緒池。

相關推薦

android universal image loader 緩衝原理

1. 功能介紹 1.1 Android Universal Image Loader Android Universal Image Loader 是一個強大的、可高度定製的圖片快取,本文簡稱為UIL。 簡單的說 UIL 就做了一件事——獲取圖片並顯示在相應的控制元件上。 1.2 基本

Android-Universal-Image-Loader三大組件DisplayImageOptions、ImageLoader、ImageLoaderConfiguration

根據 GridView ESS ted activit close except spa mat Android-Universal-Image-Loader三大組件DisplayImageOptions、ImageLoader、ImageLoaderConfigurati

Android-Universal-Image-Loader三大元件DisplayImageOptions、ImageLoader、ImageLoaderConfiguration

一、介紹  Android-Universal-Image-Loader是一個開源的UI元件程式,該專案的目的是提供一個可重複使用的儀器為非同步影象載入,快取和顯示。所以,如果你的程式裡需要這個功能的話,那麼不妨試試它。因為已經封裝好了一些類和方法。我們 可以直接拿來用了。而不用重複去寫了。其實,寫

Android-Universal-Image-Loader 學習筆記(二)載入圖片原理

public void displayImage(String uri, ImageAware imageAware, DisplayImageOptions options, ImageLoadingListener listener, ImageLoadingProgressListener pro

Android Universal Image Loader學習筆記

2、整個UIL庫分為ImageLoaderEngine,Cache及ImageDownloader,BitmapDisplayer,Bitmapprocessor ~流程:ImageLoader收到載入及顯示的任務,並將它交給ImageLoaderEngi

android Universal-Image-Loader

一、介紹  (一)、概要:         Android-Universal-Image-Loader是一個開源的UI元件程式,該專案的目的是實現可重複使用的非同步影象載入、快取和顯示。所以,如果你的程式裡需要這個功能的話,使用它,因為已經封裝

android--------Universal-Image-Loader圖片載入框架和結合LruCache快取圖片

本部落格包含包含Android-Universal-Image-Loader 網路圖片載入框架實現圖片載入和結合universal-image-loader與LruCache來自定義快取圖片,可以設定快取與不快取。 Android-Universal-Image-Load

Android-Universal-Image-Loader框架的基本使用

首先在官網下載:  https://github.com/nostra13/Android-Universal-Image-Loader  下載它的jar檔案  然後開啟我們的Android Studio新建一個工程Imagetest. 將當前的工程結構android切換到

Android Universal-Image-Loader,Volley,Picasso、Fresco和Glide五大Android開源元件載入網路圖片的優缺點比較

關於 Fresco Facebook最近推出了一款用於Android應用中展示圖片的強大圖片庫Fresco,它能夠從網路、本地儲存和本地資源中載入圖片。而且,為了節省資料和CPU,它擁有三級快取。 Fresco 是一個強大的圖片載入元件。 Fresco 中設計有一個叫做 image pipeline

Android-Universal-Image-Loader 學習筆記(一) 基本配置與使用

package com.nostra13.universalimageloader.core; import android.content.Context; import android.content.res.Resources; import android.util.DisplayMetrics;

分析Android-Universal-Image-Loader的快取處理機制

    最近看了UIL中的快取實現,才發現其實這個東西不難,沒有太多的程序排程,沒有各種記憶體讀取控制機制、沒有各種異常處理。反正UIL中不單程式碼寫的簡單,連處理都簡單。但是這個類庫這麼好用,又有這麼多人用,那麼非常有必要看看他是怎麼實現的。先了解UIL中快取流程的原理

Android-Universal-Image-Loader 屬性設定

設定Android-Universal-Image-Loader快取圖片的目錄其預設的快取目錄是mnt/sdcard/Android/data/your project/下,因為沒有提供介面,所以想修改只能改其原始碼。1.到https://github.com/nostra1

Android-Universal-Image-Loader的工具類封裝

在Android開發中對圖片資源的處理已經司空見慣了,如果還是使用Android API提供的方法來處理圖片(尤其是網路圖片),不僅複雜工作量大,而且還達不到好的一個效果.所以最終選擇一些圖片處理框架,如Android-Universal-Image-Loader,pica

Android-Universal-Image-Loader 圖片非同步載入類庫的使用(超詳細配置)

      這個圖片非同步載入並快取的類已經被很多開發者所使用,是最常用的幾個開源庫之一,主流的應用,隨便反編譯幾個火的專案,都可以見到它的身影。        可是有的人並不知道如何去使用這庫如何進行配置,網上查到的資訊對於剛接觸的人來說可能太少了,下面我就把我使用過程中

使用 Android-Universal-Image-Loader 圖片載入框架,載入圖片

特點 多執行緒下載圖片,圖片可以來源於網路,檔案系統,專案資料夾assets中以及drawable中等 支援隨意的配置ImageLoader,例如執行緒池,圖片下載器,記憶體快取策略,硬碟快取策略,圖片顯示選項以及其他的一些配置 支援圖片

Android 開源框架Universal-Image-Loader完全解析(二)--- 圖片快取策略

本篇文章繼續為大家介紹Universal-Image-Loader這個開源的圖片載入框架,介紹的是圖片快取策略方面的,如果大家對這個開源框架的使用還不瞭解,大家可以看看我之前寫的一篇文章Android 開源框架Universal-Image-Loader完全解析(一)---

Android 使用圖片異步載入框架Universal Image Loader的問題

loader mar fill splay con iss text blog option 使用的Jar包 問題: optionsm = new DisplayImageOptions.Builder() .displayer(new

開源項目Universal Image Loader for Android 說明文檔 (1) 簡單介紹

bst 成功 開源 ica ctu structure 使用 說明 由於  When developing applications for Android, one often facesthe problem of displa

Android熱修復技術原理(最新最全版本)

總結 核心 桌面圖標 實時 開源 穩定性 安卓 定義 check 本文框架 什麽是熱修復? 熱修復框架分類 技術原理及特點 Tinker框架解析 各框架對比圖 總結 ??通過閱讀本文,你會對熱修復技術有更深的認知,本文會列出各類框架的優缺點以及技術原理,文章末尾簡單描述

Android官方架構組件:Lifecycle&迪士尼彩樂園網站架設原理分析

ner 觀察者 and 順序 觸發 組件 oncreate mcr save 我們先將重要的這些類挑選出來: LifecycleObserver接口( Lifecycle觀察者):實現該接口的類,通過註解的方式,可以通過被LifecycleOwner類的addObserve