轉載請標明出處:
http://blog.csdn.net/developer_jiangqq/article/details/50439814
本文出自:【江清清的博客】
(一).前言:
已經半個月沒有更新文章了,一方面是最近工作比較忙,另一方面我也在選擇博客的題材。這次我主要講解平時用的比較多的圖片加載框架ImageLoader。雖然這個框架前不久作者已經停止更新了,不過這個圖片加載框架我已經用了很久了。我深知框架使用簡便是一方面,但是如果能夠不僅會使用而且能夠深知其中實現的原理才是最重要的。所以我把ImageLoader項目所有的代碼閱讀了一遍並且給每個類和相關方法添加了中文版本的注釋。
本例以及UIL框架全部中文版本注釋項目已經更新到github,有興趣大家可以去clone,start或者fork。
地址https://github.com/jiangqqlmj/Android-Universal-Image-Loader-Modify
[順便說一下,可以微信掃描關注左側的二維碼關注訂閱號,獲取最新文章哈~]
本次專題的文章主要會涉及到以下部分ImageLoader的介紹和使用,部分重要模塊分析以及相關源碼講解。今天我們主要進行第一部分的講解(ImageLoader基礎介紹和使用講解)。
(二).ImageLoader基本介紹:
我們在開發APP的時候肯定遇到加載圖片的需求尤其是列表需要加載大量圖片的時候,那么我們勢必需要進行下載圖片並且進行顯示。但是由於內存等各方面的問題多多少少會遇到一些問題;例如:列表加載圖片,圖片錯亂分布啦。或者出現OOM問題啦~~這時候我們需要開發圖片異步加載並且可以適當壓縮框架。例如:UIL(Universal-Image-Loader,github項目地址UIL項目地址)除此之外還有其他很多框架Glide,Fresco,Picasso等等很多。后面幾個現在用的比較多而且還在更多。后面的文章我這邊也會分享其他的圖片加載框架。
UIL(Universal-Image-Loader)旨在提供一個強大的、靈活的和高度可定制的工具圖像加載、緩存和顯示功能。並且提供了許多配置選項和良好控制圖像加載和緩存的過程。所以在之前長久的一段時間里,該框架的使用非常廣且很方便哦。
UIL框架特點:
- 支持多線程圖片加載(同步或者異步)
- 支持自定義配置ImageLoader,例如線程池,圖片下載器,內存緩存策略,硬盤緩存策略,圖片顯示選項以及其他的一些配置
- 支持自定義配置圖片顯示,例如:緩存開關選擇,界面選項,圖片加載進度以及顯示
- 支持圖片內存緩存或者文件系統,設備SD緩存
- 支持圖片加載進度監聽(包括圖片下載進度監聽)
- 支持框架更多工具類的擴展
- 同樣可以支持例如ListView,GridView進行滑動的時候暫停或者恢復圖片加載顯示等功能。
- 當然還有其他很過特點,具體大家讀了源碼就會知道啦….
(三).ImageLoader快速安裝:
如果我們要使用ImageLoader大家都可以項目地址下載一份代碼其中會有imageLoader的jar包引入到項目就可以了。整體項目中內容文件夾如下:
3.1.我們下載imageloader的jar包到我們項目libs文件夾中,然后關聯即可(universal-image-loader-1.9.5.jar):
3.2.現在我們采用Android Studio開發項目了,我們只需要build.gradle中添加以下依賴即可:
compile'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
3.3.項目配置文件需要添加相關權限(主要為訪問網絡權限,如果圖片需要sdcard緩存還需要多添加一個權限)
- <manifest>
- <!-- Include following permission if you load images from Internet -->
- <uses-permission android:name="android.permission.INTERNET" />
- <!-- Include following permission if you want to cache images on SD card -->
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- ...
- </manifest>
3.4.最后我們需要在第一次使用ImageLoader之前,做一下ImageLoader的基礎配置,該項配置可以在application或者activity中做即可,如下方式:
- ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
- ...
- .build();
- ImageLoader.getInstance().init(config);
3.5.下面我們就可以具體使用ImageLoader來進行加載和顯示圖片啦。
(四).ImageLoader全局配置項(Configuration)
上面3.4中我們講到了ImageLoader在使用之前需要進行全局配置一下。OK,ImageLoader給我們提供了一個ImageLoaderConfiguration來進行全局設置ImageLoader。不過該設置是全局的,我們只需要設置一次即可了。
查看ImageLoader文檔以及ImageLoaderConfiguration源碼發現,該為我們提供了所有的配置項都是可選的。除非你需要自定義設置,模板我們可以調用該其中默認構造的方法如下:
ImageLoaderConfiguration configuration=ImageLoaderConfiguration.createDefault(this);
ImageLoader.getInstance().init(configuration);
上面的createDefault方法會給我們默認初始化一些配置項,具體所有配置可選項如下圖:
上面包括設置緩存大小,任務執行器,線程池線程數量,線程權重,任務執行算法,磁盤緩存大小,緩存文件數量,緩存文件命名規則,圖片下載器,解碼器,圖片顯示配置項等等。大家可以隨意根據項目實際情況配置即可了。
(五).ImageLoader圖片Display配置項(Display Options)
上面我們講到了ImageLoader的全局配置,在對於圖片顯示的時候(ImageLoader.displayImage(…)的時候),我們還可以設置圖片顯示的參數(主要使用DisplayImageOptions)。Display Options(顯示可選項)用於每次圖片顯示任務的時候(ImageLoader.displayImage()該方法被調用)。
【注意】如果我們沒有設置圖片顯示配置項,那么我在顯示圖片的時候會默認調用圖片默認顯示方式。具體可選配置項如下:
上面包括圖片加載過程中,圖片地址為空以及圖片加載失敗的圖片,加載延時,開啟內存緩存以及磁盤緩存,圖片縮放類型,圖片編碼類型以及圖片顯示加載器等等參數。具體根據實際項目選擇配置即可。
(六).ImageLoader加載圖片講解
現在我們開始講解使用ImageLoader加載圖片啦,在這之前大家一定要按照第三點的內容ImageLoader要安裝一下以及做一下基本權限以及全局配置哦~下面我們首先看一下ImageLoader來顯示圖片的幾個方法:
查看上面ImageLoader的方法圖看:主要分為下面三種方式加載圖片啦~我們在項目中一般使用前兩種哦(displayImage和loadImage),因為這兩種是異步的,另外的loadImageSync是同步的啦。
6.1.dispalyImage()方法使用講解:
6.1.1本例中我ImageLoader全局是采用默認配置的如下:
- public class UILApplication extends Application {
- @Override
- public void onCreate() {
- super.onCreate();
- initImageLoader();
- }
- private void initImageLoader(){
- ImageLoaderConfiguration configuration=ImageLoaderConfiguration.createDefault(this);
- ImageLoader.getInstance().init(configuration);
- }
- }
實例布局文件如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- androidlayout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:gravity="center">
- <ImageView
- android:id="@+id/test_img_one"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/ic_data_loading"/>
- </LinearLayout>
然后Activitity實例化控件以及ImageLoader,調用displayImage方法即可:
- ImageView test_img_one=(ImageView)this.findViewById(R.id.test_img_one);
- ImageLoader.getInstance().displayImage(ImageDataUtils.ImagesUtils[0],test_img_one);
6.1.2.上邊我們采用displayImage是兩個參數的方法,我們同時可以在這邊加入圖片顯示參數配置如下即可:
- ImageView test_img_one=(ImageView)this.findViewById(R.id.test_img_one);
- DisplayImageOptions options=new DisplayImageOptions.Builder()
- .showImageOnLoading(R.drawable.ic_data_loading)
- .showImageOnFail(R.drawable.ic_data_error)
- .cacheInMemory(true)
- .cacheOnDisk(true)
- .build();
- ImageLoader.getInstance().displayImage(ImageDataUtils.ImagesUtils[1],test_img_one,options);
上面我們配置加載過程中和加載失敗顯示的圖片以及開啟內存和磁盤緩存功能運行效果如下:
6.1.3.在顯示的時候我們還可以加入圖片的目標尺寸,如下:
- ImageSize size=new ImageSize(100,50);
- ImageLoader.getInstance().displayImage(ImageDataUtils.ImagesUtils[1],test_img_one,size);
這邊構造一個ImageSize對象來定義目標圖片的寬度和高度,傳入寬100,高50,運行效果如下:
6.1.4.除了上面的三個顯示重載方法之外,我們還可以傳入一個圖片加載進度監聽器進入,具體接口回調我們放入到下面loadImage()方法中講解。
6.2.loadImage()方法使用講解:
上面6.1我們已經對displayImage()方法做了一些講解,現在我們對於另外一個異步加載圖片方法loadImage做一下講解。本例中我這邊采用TwoActivity以及一個簡單布局:該布局中就放入一個ImageView即可。全局配置和上面一樣。
6.2.1.loadImage(Stringuri, ImageLoadingListener listener)
該傳入兩個參數第一個為圖片下載地址,第二個為圖片加載監聽器首先采用默認的接口如下設置:
- ImageView test_img_two=(ImageView)this.findViewById(R.id.test_img_two);
- ImageLoader.getInstance().loadImage(ImageDataUtils.ImagesUtils[3], new ImageLoadingListener() {
- @Override
- public void onLoadingStarted(String imageUri, View view) {
- //圖片開始加載的時候調用
- Log.d("zttjiangqq","onLoadingStarted...");
- }
- @Override
- public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
- //圖片加載失敗調用
- Log.d("zttjiangqq","onLoadingFailed...");
- }
- @Override
- public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
- //圖片加載完成調用
- Log.d("zttjiangqq","onLoadingComplete...");
- test_img_two.setImageBitmap(loadedImage);
- }
- @Override
- public void onLoadingCancelled(String imageUri, View view) {
- //圖片加載取消調用
- Log.d("zttjiangqq","onLoadingCancelled...");
- }
- });
具體運行打印的日志和運行結果如下:
我們看到使用ImageLoadingListener接口必須要實現接口中四個方法,但是我們平時實際情況下可能不需要回調那么多方法,不錯的是UIL給我們提供了一個類SimpleImageLoadingListener類,該類實現了ImageLoadingListener接口。我們傳入該實現類即可,這樣我們重寫實際所需的方法就方便多了。具體實例如下
- ImageLoader.getInstance().loadImage(ImageDataUtils.ImagesUtils[4],new SimpleImageLoadingListener(){
- @Override
- public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
- super.onLoadingComplete(imageUri, view, loadedImage);
- //圖片加載完成時候調用
- Log.d("zttjiangqq","onLoadingComplete...");
- test_img_two.setImageBitmap(loadedImage);
- }
- @Override
- public void onLoadingStarted(String imageUri, View view) {
- super.onLoadingStarted(imageUri, view);
- //圖片開始加載的時候調用
- Log.d("zttjiangqq", "onLoadingStarted...");
- }
- });
這邊我只重寫了onLoadingComplete和onLoadingStarted兩個方法,代碼量上面就減少了很多。
6.2.2.loadImage(Stringuri, ImageSize targetImageSize, DisplayImageOptions options,ImageLoadingListenerlistener)
該加載圖片方法6.1中講得差不多,我們同時可以傳入圖片顯示配置項,具體示例如下:
- DisplayImageOptions options=new DisplayImageOptions.Builder()
- .showImageOnLoading(R.drawable.ic_data_loading)
- .showImageOnFail(R.drawable.ic_data_error)
- .cacheInMemory(true)
- .cacheOnDisk(true)
- .build();
- ImageLoader.getInstance().loadImage(ImageDataUtils.ImagesUtils[5],options,new SimpleImageLoadingListener(){
- @Override
- public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
- super.onLoadingComplete(imageUri, view, loadedImage);
- //圖片加載完成時候調用
- Log.d("zttjiangqq","onLoadingComplete...");
- test_img_two.setImageBitmap(loadedImage);
- }
- });
6.2.3.loadImage(Stringuri, ImageSize targetImageSize, ImageLoadingListener listener)
該加載圖片方式我們可以傳入目標圖片的尺寸大小,用起來直接構造一個ImageSize傳入進去就可以了。具體方法如下:
- ImageSize size=new ImageSize(100,50);
- ImageLoader.getInstance().loadImage(ImageDataUtils.ImagesUtils[6],size,new SimpleImageLoadingListener(){
- @Override
- public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
- super.onLoadingComplete(imageUri, view, loadedImage);
- //圖片加載完成時候調用
- Log.d("zttjiangqq","onLoadingComplete...");
- test_img_two.setImageBitmap(loadedImage);
- }
- });
6.2.4.主要就是以上幾種方式,其他的圖片加載方法和以上的差不多,只需要傳入對應的參數就可以了。
(七).最后總結
今天我們對於UIL(Universal-Image-Loader)開源框架的介紹和基本使用做了相關講解,包括介紹,安裝,配置以及基本使用方面。下一講會着重講解該開源組件幾個核心的類以及相關使用注意事項。
本例以及UIL框架全部中文版本注釋項目已經更新到github,有興趣大家可以去clone,start或者fork。
地址https://github.com/jiangqqlmj/Android-Universal-Image-Loader-Modify
尊重原創,轉載請注明:From Sky丶清(http://blog.csdn.net/developer_jiangqq) 侵權必究!