GitHub https://github.com/nostra13/Android-Universal-Image-Loader
先來看一下Android-Universal-Image-Loader架構的用法;
1、初始化ImageLoaderConfiguration(全域的,在整個application中初始化configuration,配置緩衝、載入線程等)
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()).threadPriority(Thread.NORM_PRIORITY - 2)// 設定線程的優先順序.denyCacheImageMultipleSizesInMemory()// 當同一個Uri擷取不同大小的圖片,緩衝到記憶體時,只緩衝一個。預設會緩衝多個不同的大小的相同圖片.discCacheFileNameGenerator(new Md5FileNameGenerator())// 設定快取檔案的名字.discCacheFileCount(60)// 快取檔案的最大個數.tasksProcessingOrder(QueueProcessingType.LIFO)// 設定圖片下載和顯示的工作隊列排序.build();// Initialize ImageLoader with configurationImageLoader.getInstance().init(config);
3、建立圖片顯示選項:DisplayImageOptions options(根據不同的載入圖片顯示不同而構造不同的選項,主要配置圖片載入過程中顯示配置,緩衝,顯示動畫);
DisplayImageOptions options;options = new DisplayImageOptions.Builder().showStubImage(R.drawable.ic_launcher)// 設定圖片在下載期間顯示的圖片.showImageForEmptyUri(R.drawable.ic_launcher)// 設定圖片Uri為空白或是錯誤的時候顯示的圖片.showImageOnFail(R.drawable.ic_launcher)// 設定圖片載入/解碼過程中錯誤時候顯示的圖片.cacheInMemory(true)// 是否緩存都內存中.cacheOnDisc(true)// 是否緩存到sd卡上.displayer(new RoundedBitmapDisplayer(20)).build();
4、通過ImageLoader顯示圖片
// ImageLoaderImageLoader imageLoader = ImageLoader.getInstance();// 第一個參數是uri,第二個參數是顯示圖片的imageView,第三個參數是剛剛構造的圖片顯示選項,第四個參數是載入的回調方法,displayImage有很多重載方法這中介其中一種;imageLoader.displayImage(imageUrls[position], holder.image, options, loadingListener)
要學習更詳細使用方法,官方的demo直接在上面連結裡面有下載;
嘿嘿,開始覺得上面這用法看起來是有點多,且感覺有點麻煩,但仔細研究你會發現它的功能之強大,從設定載入線程優先順序別、圖片緩衝、圖片顯示包括顯示動畫等都在考慮在其中,它還有非常好的擴充性,使用者可以根據需求配置各種不同的顯示效果、載入動畫等,綜合來看設計是很巧妙的,下面來體會一下這個開源架構的強大設計:
----------------------------------------------分割線------------------------------------------------------------------------
架構特點:
1、多線程的映像載入(線程池的大小,HTTP選項紗、線程式控制件等);
2、能夠很好的監聽載入過程;
3、圖片顯示配置介面(動畫,圓角可擴充);
4、記憶體和磁碟快取;
5、擴充性強,研發人員只需要根據需求實現它提供的各種介面即可;
架構裡面使用最多的是建造者模式與策略模式,要從整個包結構開始看起才能更好的熟悉架構設計,才能更好的擴充它使之與自己工程融為一體;
看圖,為整個開源架構的包結構:
嘖嘖,這裡就不詳敘了,架構裡面命名很透徹,基本見名知意,它總共分為幾大模組:
1、緩衝模組;
為緩衝模組包結構圖:
主要分為disc和memZ喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcnmjrNXi1vfSqsrHtMXFzLu6tOa4+sTatOa7urTmudzA7aOsuf6jrNWmv7S96cO0tuDA4KOsxuTKtbTzsr+31srHudm3vczhuam4+M7Sw8e1xLLfwtTKtc/Wo6zV4sDv1vfSqtPDtcTKx7LfwtTEo8q9o6zAtLfWzvbSu8/C1eK49rD8veG5uaO6PGJyPgrG5Mq11eLA787Sw8fWu9KqudjXosG9uPbA4KOst9ax8MrHZGlzY7rNbWVtb3J5z8LD5rXERGlzY0NhY2hlQXdhcmWhok1lbW9yeUNhY2hlQXdhcmVy1eLBvbj2vdO/2qOsy/zM4bmpuPjBy87Sw8fN4rK/tffTw8v50OjSqrXEvdO/2qOszeKyv9KyysfWsb3TyrnTw9Xiwb249r3Tv9qjrLb4aW1wbMDvw+bU8srHttTV4sG9uPbA4LXEyrXP1qOsvau907/atcTQ0M6qt723qL340NCyu82stcSy38LUyrXP1ry01ebV/da00NC1xLT6wus7ILb4ztLDx9Do0qrKudPDtcTKsbryo6zWu9Do0qrU2sXk1sNJbWFnZUxvYWRlckNvbmZpZ3VyYXRpb261xMqxuvKjrLj5vt3Q6NKqxeTWw7bU06a1xERpc2NDYWNoZUF3YXJloaJNZW1vcnlDYWNoZUF3YXJlcrXE19PA4Mq1z9a8tL/Jo7s8L3A+CjxwPiDV4tH51/a8tL3hubnH5c76o6y2+MfStbHO0sPH09DX1Ly6tcTQ6MfztcTKsbryo6zO0sPH1rvQ6NKqvMyz0NXiwb249r3Tv9qjrLao0uXX1Ly6tcSy38LU0NDOqry0v8mjrLK70OjSqtDeuMTIzrrOtPrC68LfvK07IDwvcD4KPHA+MqGiveLC68Sjv+mjujxicj4KIM/CzbzOqr3iwuvEo7/psPy94bm5zbyjujwvcD4KPHA+PGltZyBzcmM9"http://www.2cto.com/uploadfile/Collfiles/20140403/2014040309150567.png" alt="\">
看似簡單,姑且就當做一個模組吧,結構跟緩衝模組類似,我們主要關注ImageDecoder介面,它只有一個方法Bitmap decode(ImageDecodingInfo imageDecodingInfo),其意根據imageDecodingInfo提供給他的解碼資訊,進行解碼,得到我們需要的bitmap;這裡應該就明白這個模組的功能了吧!
官方只提供給了我們一個實作類別即BaseImageDecoder,這裡實現細節就不記錄了。
3、顯示模組:
為顯示模組包結構圖:
額,多麼熟悉的結構,只需要看一個介面BitmapDisplayer,裡面只有一個方法display,即整個模組目的只有一個,顯示圖片,至於如何顯示,官方也提供給了我們幾種行為策略:FadeInBitmapDisplayer(漸層顯示)、RoundedBitmapDisplayer(圖片圓角顯示)、RoundedVignetteBitmapDisplayer(沒玩過,意思是裝飾圓角麼,嘿嘿)!
當然這隻是一點點,具體你要怎麼顯示,當然是天高任你飛了,只要實現BitmapDisplayer這個介面,就行了。
4、下載模組:
見圖:
結構再也不陌生了,嘖嘖,此模組核心介面ImageDownloader,圖片下載,這個介面裡面定義了一個內部枚舉類Scheme,不得不被如此強大的功能折服了:
Scheme代碼:
/** Represents supported schemes(protocols) of URI. Provides convenient methods for work with schemes and URIs. */public enum Scheme {HTTP("http"), HTTPS("https"), FILE("file"), CONTENT("content"), ASSETS("assets"), DRAWABLE("drawable"), UNKNOWN("");private String scheme;private String uriPrefix;Scheme(String scheme) {this.scheme = scheme;uriPrefix = scheme + "://";}/** * Defines scheme of incoming URI * * @param uri URI for scheme detection * @return Scheme of incoming URI */public static Scheme ofUri(String uri) {if (uri != null) {for (Scheme s : values()) {if (s.belongsTo(uri)) {return s;}}}return UNKNOWN;}private boolean belongsTo(String uri) {return uri.toLowerCase(Locale.US).startsWith(uriPrefix);}/** Appends scheme to incoming path */public String wrap(String path) {return uriPrefix + path;}/** Removed scheme part ("scheme://") from incoming URI */public String crop(String uri) {if (!belongsTo(uri)) {throw new IllegalArgumentException(String.format("URI [%1$s] doesn't have expected scheme [%2$s]", uri, scheme));}return uri.substring(uriPrefix.length());}}
Scheme定義了支援的下載圖片地址協議,包括content,assets,drawable下的圖片都可以做為uri來下載,通過將assets,drawable地址前面加上協議頭,來統一管理圖片源,著實高;並且給出了判斷是否是支援類型的各種方法;
整個顯示流程就是這樣:下載-->緩衝-->解碼-->顯示,生生不息啊。
5、listener包,這裡僅僅是提供給我們了各樣的回調,通過這裡,我們大致能看到這個架構能讓我們做什麼,能否實現我們的需求,當然,你夠熟悉它,你也可以根據需求添加自己的回調;
6、util包,工具類包!
上面幾個模組的設計都是可擴充的,可以在不修改整體代碼的情況下通過實現不同的策略行為達到我們的需求。一個好的架構既有強大的功能,又有良好的結構性與擴充性;
嘖,怎麼越看越空虛,想想自己之前寫的圖片下載工具,考慮的方面與功能簡直弱爆了!