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 configuration
- ImageLoader.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顯示圖片
- // ImageLoader
- ImageLoader imageLoader = ImageLoader.getInstance();
- // 第一個參數是uri,第二個參數是顯示圖片的imageView,第三個參數是剛剛構造的圖片顯示選項,第四個參數是加載的回調方法,displayImage有很多重載方法這中介其中一種;
- imageLoader.displayImage(imageUrls[position], holder.image, options, loadingListener)
要學習更詳細使用方法,官方的demo直接在上面鏈接裏面有下載;
嘿嘿,開始覺得上面這用法看起來是有點多,且感覺有點麻煩,但仔細研究你會發現它的功能之強大,從設置加載線程優先級別、圖片緩存、圖片顯示包括顯示動畫等都在考慮在其中,它還有非常好的擴展性,用戶可以根據需求配置各種不同的顯示效果、加載動畫等,綜合來看設計是很巧妙的,下面來體會一下這個開源框架的強大設計:
----------------------------------------------分割線------------------------------------------------------------------------
框架特點:
1、多線程的圖像加載(線程池的大小,HTTP選項紗、線程控件等);
2、能夠很好的監聽加載過程;
3、圖片顯示配置接口(動畫,圓角可擴展);
4、內存和磁盤高速緩存;
5、擴展性強,研發人員只需要根據需求實現它提供的各種接口即可;
框架裏面使用最多的是建造者模式與策略模式,要從整個包結構開始看起才能更好的熟悉框架設計,才能更好的擴展它使之與自己工程融爲一體;
看圖,下圖爲整個開源框架的包結構:
嘖嘖,這裏就不詳敘了,框架裏面命名很透徹,基本見名知意,它總共分爲幾大模塊:
1、緩存模塊;
下圖爲緩存模塊包結構圖:
主要分爲disc和memory,這主要是磁盤緩存跟內存緩存管理,哈,咋看介麼多類,其實大部分是官方提供給我們的策略實現,這裏主要用的是策略模式,來分析一下這個包結構:
其實這裏我們只要關注兩個類,分別是disc和memory下面的DiscCacheAware、MemoryCacheAwarer這兩個接口,它提供給了我們外部調用所需要的接口,外部也是直接使用這兩個接口,而impl裏面則是對這兩個類的實現,將接口的行爲方法進行不同的策略實現即真正執行的代碼; 而我們需要使用的時候,只需要在配置ImageLoaderConfiguration的時候,根據需要配置對應的DiscCacheAware、MemoryCacheAwarer的子類實現即可;
這樣做即結構清晰,而且當我們有自己的需求的時候,我們只需要繼承這兩個接口,定義自己的策略行爲即可,不需要修改任何代碼邏輯;
2、解碼模塊:
下圖爲解碼模塊包結構圖:
看似簡單,姑且就當做一個模塊吧,結構跟緩存模塊類似,我們主要關注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包,工具類包!
上面幾個模塊的設計都是可擴展的,可以在不修改整體代碼的情況下通過實現不同的策略行爲達到我們的需求。一個好的框架既有強大的功能,又有良好的結構性與擴展性;