新建一個MyApplication繼承Application,並在onCreate()中創建ImageLoader的配置參數,並初始化到ImageLoader中代碼如下
1 package com.example.uil; 2 3 import com.nostra13.universalimageloader.core.ImageLoader; 4 import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; 5 6 import android.app.Application; 7 8 public class MyApplication extends Application { 9 10 @Override 11 public void onCreate() { 12 super.onCreate(); 13 14 //創建默認的ImageLoader配置參數 15 ImageLoaderConfiguration configuration = ImageLoaderConfiguration 16 .createDefault(this); 17 18 //Initialize ImageLoader with configuration. 19 ImageLoader.getInstance().init(configuration); 20 } 21 22 }
ImageLoaderConfiguration是圖片加載器ImageLoader的配置參數,使用了建造者模式,這里是直接使用了 createDefault()方法創建一個默認的ImageLoaderConfiguration,當然我們還可以自己設置 ImageLoaderConfiguration,設置如下
1 //緩存文件夾 2 File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache"); 3 File cacheDir = StorageUtils.getCacheDirectory(context); //緩存文件夾路徑 4 ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context) 5 .memoryCacheExtraOptions(480, 800) // default = device screen dimensions 內存緩存文件的最大長寬 6 .diskCacheExtraOptions(480, 800, null) // 本地緩存的詳細信息(緩存的最大長寬),最好不要設置這個 7 .taskExecutor(...) 8 .taskExecutorForCachedImages(...) 9 .threadPoolSize(3) // default 線程池內加載的數量 10 .threadPriority(Thread.NORM_PRIORITY - 2) // default 設置當前線程的優先級 11 .tasksProcessingOrder(QueueProcessingType.FIFO) // default 12 .denyCacheImageMultipleSizesInMemory() 13 .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) //可以通過自己的內存緩存實現 14 .memoryCacheSize(2 * 1024 * 1024) // 內存緩存的最大值 15 .memoryCacheSizePercentage(13) // default 16 .diskCache(new UnlimitedDiscCache(cacheDir)) // default 可以自定義緩存路徑 17 .diskCacheSize(50 * 1024 * 1024) // 50 Mb sd卡(本地)緩存的最大值 18 .diskCacheFileCount(100) // 可以緩存的文件數量 19 // default為使用HASHCODE對UIL進行加密命名, 還可以用MD5(new Md5FileNameGenerator())加密 20 .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) 21 .imageDownloader(new BaseImageDownloader(context)) // default 22 .imageDecoder(new BaseImageDecoder()) // default 23 .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default 24 .writeDebugLogs() // 打印debug log 25 .build(); //開始構建
上面的這些就是所有的選項配置,我們在項目中不需要每一個都自己設置,一般使用createDefault()創建的 ImageLoaderConfiguration就能使用,然后調用ImageLoader的init()方法將 ImageLoaderConfiguration參數傳遞進去,ImageLoader使用單例模式。
1 <manifest> 2 <uses-permission android:name="android.permission.INTERNET" /> 3 <!-- Include next permission if you want to allow UIL to cache images on SD card --> 4 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 5 ... 6 <application android:name="MyApplication"> 7 ... 8 </application> 9 </manifest>
接下來我們就可以來加載圖片了,首先我們定義好Activity的布局文件
1 <?xml version="1.0" encoding="utf-8"?> 2 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="fill_parent" 4 android:layout_height="fill_parent"> 5 6 <ImageView 7 android:layout_gravity="center" 8 android:id="@+id/image" 9 android:src="@drawable/ic_empty" 10 android:layout_width="wrap_content" 11 android:layout_height="wrap_content" /> 12 13 </FrameLayout>
1 final ImageView mImageView = (ImageView) findViewById(R.id.image); 2 String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg"; 3 4 ImageLoader.getInstance().loadImage(imageUrl, new ImageLoadingListener() { 5 6 @Override 7 public void onLoadingStarted(String imageUri, View view) { 8 9 } 10 11 @Override 12 public void onLoadingFailed(String imageUri, View view, 13 FailReason failReason) { 14 15 } 16 17 @Override 18 public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { 19 mImageView.setImageBitmap(loadedImage); 20 } 21 22 @Override 23 public void onLoadingCancelled(String imageUri, View view) { 24 25 } 26 }); 27 傳入圖片的url和ImageLoaderListener, 在回調方法onLoadingComplete()中將loadedImage設置到ImageView上面就行了,如果你覺得傳入 ImageLoaderListener太復雜了,我們可以使用SimpleImageLoadingListener類,該類提供了 ImageLoaderListener接口方法的空實現,使用的是缺省適配器模式 28 final ImageView mImageView = (ImageView) findViewById(R.id.image); 29 String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg"; 30 31 ImageLoader.getInstance().loadImage(imageUrl, new SimpleImageLoadingListener(){ 32 33 @Override 34 public void onLoadingComplete(String imageUri, View view, 35 Bitmap loadedImage) { 36 super.onLoadingComplete(imageUri, view, loadedImage); 37 mImageView.setImageBitmap(loadedImage); 38 } 39 40 });
如果我們要指定圖片的大小該怎么辦呢,這也好辦,初始化一個ImageSize對象,指定圖片的寬和高,代碼如下
1 final ImageView mImageView = (ImageView) findViewById(R.id.image); 2 String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg"; 3 4 ImageSize mImageSize = new ImageSize(100, 100); 5 6 ImageLoader.getInstance().loadImage(imageUrl, mImageSize, new SimpleImageLoadingListener(){ 7 8 @Override 9 public void onLoadingComplete(String imageUri, View view, 10 Bitmap loadedImage) { 11 super.onLoadingComplete(imageUri, view, loadedImage); 12 mImageView.setImageBitmap(loadedImage); 13 } 14 15 });
上面只是很簡單的使用ImageLoader來加載網絡圖片,在實際的開發中,我們並不會這么使用,那我們平常會怎么使用呢?我們會用到 DisplayImageOptions,他可以配置一些圖片顯示的選項,比如圖片在加載中ImageView顯示的圖片,是否需要使用內存緩存,是否需 要使用文件緩存等等,可供我們選擇的配置如下
1 DisplayImageOptions options = new DisplayImageOptions.Builder() 2 .showImageOnLoading(R.drawable.ic_stub) // 設置圖片下載期間顯示的圖片 3 .showImageForEmptyUri(R.drawable.ic_empty) // 設置圖片Uri為空或是錯誤的時候顯示的圖片 4 .showImageOnFail(R.drawable.ic_error) // 設置圖片加載或解碼過程中發生錯誤顯示的圖片 5 .resetViewBeforeLoading(false) // default 設置圖片在加載前是否重置、復位 6 .delayBeforeLoading(1000) // 下載前的延遲時間 7 .cacheInMemory(false) // default 設置下載的圖片是否緩存在內存中 8 .cacheOnDisk(false) // default 設置下載的圖片是否緩存在SD卡中 9 .preProcessor(...) 10 .postProcessor(...) 11 .extraForDownloader(...) 12 .considerExifParams(false) // default 13 .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default 設置圖片以如何的編碼方式顯示 14 .bitmapConfig(Bitmap.Config.ARGB_8888) // default 設置圖片的解碼類型 15 .decodingOptions(...) // 圖片的解碼設置 16 .displayer(new SimpleBitmapDisplayer()) // default 還可以設置圓角圖片new RoundedBitmapDisplayer(20) 17 .handler(new Handler()) // default 18 .build(); 19 // 20 .imageScaleType(ImageScaleType imageScaleType) //設置圖片的縮放方式 21 縮放類型mageScaleType: 22 EXACTLY :圖像將完全按比例縮小的目標大小 23 EXACTLY_STRETCHED:圖片會縮放到目標大小完全 24 IN_SAMPLE_INT:圖像將被二次采樣的整數倍 25 IN_SAMPLE_POWER_OF_2:圖片將降低2倍,直到下一減少步驟,使圖像更小的目標大小 26 NONE:圖片不會調整 27 2).displayer(BitmapDisplayer displayer) //設置圖片的顯示方式 28 顯示方式displayer: 29 RoundedBitmapDisplayer(int roundPixels)設置圓角圖片 30 FakeBitmapDisplayer()這個類什么都沒做 31 FadeInBitmapDisplayer(int durationMillis)設置圖片漸顯的時間 32 SimpleBitmapDisplayer()正常顯示一張圖片 33 //參數補充 34 .considerExifParams(true) //是否考慮JPEG圖像EXIF參數(旋轉,翻轉) 35 .displayer(new FadeInBitmapDisplayer(100))// 圖片加載好后漸入的動畫時間 36 我們將上面的代碼稍微修改下 37 final ImageView mImageView = (ImageView) findViewById(R.id.image); 38 String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg"; 39 ImageSize mImageSize = new ImageSize(100, 100); 40 41 //顯示圖片的配置 42 DisplayImageOptions options = new DisplayImageOptions.Builder() 43 .cacheInMemory(true) 44 .cacheOnDisk(true) 45 .bitmapConfig(Bitmap.Config.RGB_565) 46 .build(); 47 48 ImageLoader.getInstance().loadImage(imageUrl, mImageSize, options, new SimpleImageLoadingListener(){ 49 50 @Override 51 public void onLoadingComplete(String imageUri, View view, 52 Bitmap loadedImage) { 53 super.onLoadingComplete(imageUri, view, loadedImage); 54 mImageView.setImageBitmap(loadedImage); 55 } 56 57 });
1 final ImageView mImageView = (ImageView) findViewById(R.id.image); 2 String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg"; 3 4 //顯示圖片的配置 5 DisplayImageOptions options = new DisplayImageOptions.Builder() 6 .showImageOnLoading(R.drawable.ic_stub) 7 .showImageOnFail(R.drawable.ic_error) 8 .cacheInMemory(true) 9 .cacheOnDisk(true) 10 .bitmapConfig(Bitmap.Config.RGB_565) 11 .build(); 12 13 ImageLoader.getInstance().displayImage(imageUrl, mImageView, options);
從上面的代碼中,我們可以看出,使用displayImage()比使用loadImage()方便很多,也不需要添加 ImageLoadingListener接口,我們也不需要手動設置ImageView顯示Bitmap對象,直接將ImageView作為參數傳遞到 displayImage()中就行了,圖片顯示的配置選項中,我們添加了一個圖片加載中ImageVIew上面顯示的圖片,以及圖片加載出現錯誤顯示的 圖片,效果如下,剛開始顯示ic_stub圖片,如果圖片加載成功顯示圖片,加載產生錯誤顯示ic_error
這個方法使用起來比較方便,而且使用displayImage()方法 他會根據控件的大小和imageScaleType來自動裁剪圖片,我們修改下MyApplication,開啟Log打印
1 public class MyApplication extends Application { 2 3 @Override 4 public void onCreate() { 5 super.onCreate(); 6 7 //創建默認的ImageLoader配置參數 8 ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(this) 9 .writeDebugLogs() //打印log信息 10 .build(); 11 12 13 //Initialize ImageLoader with configuration. 14 ImageLoader.getInstance().init(configuration); 15 } 16 17 }
我們來看下圖片加載的Log信息
第一條信息中,告訴我們開始加載圖片,打印出圖片的url以及圖片的最大寬度和高度,圖片的寬高默認是設備的寬高,當然如果我們很清楚圖片的大小, 我們也可以去設置這個大小,在ImageLoaderConfiguration的選項中memoryCacheExtraOptions(int maxImageWidthForMemoryCache, int maxImageHeightForMemoryCache)
第二條信息顯示我們加載的圖片來源於網絡
第三條信息顯示圖片的原始大小為1024 x 682 經過裁剪變成了512 x 341
第四條顯示圖片加入到了內存緩存中,我這里沒有加入到sd卡中,所以沒有加入文件緩存的Log
1 imageLoader.displayImage(imageUrl, mImageView, options, new SimpleImageLoadingListener(), new ImageLoadingProgressListener() { 2 3 @Override 4 public void onProgressUpdate(String imageUri, View view, int current, 5 int total) { 6 7 } 8 });
1 //顯示圖片的配置 2 DisplayImageOptions options = new DisplayImageOptions.Builder() 3 .showImageOnLoading(R.drawable.ic_stub) 4 .showImageOnFail(R.drawable.ic_error) 5 .cacheInMemory(true) 6 .cacheOnDisk(true) 7 .bitmapConfig(Bitmap.Config.RGB_565) 8 .build(); 9 10 final ImageView mImageView = (ImageView) findViewById(R.id.image); 11 String imagePath = "/mnt/sdcard/image.png"; 12 String imageUrl = Scheme.FILE.wrap(imagePath); 13 14 // String imageUrl = "http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg"; 15 16 imageLoader.displayImage(imageUrl, mImageView, options);
當然還有來源於Content provider,drawable,assets中,使用的時候也很簡單,我們只需要給每個圖片來源的地方加上Scheme包裹起來(Content provider除外),然后當做圖片的url傳遞到imageLoader中,Universal-Image-Loader框架會根據不同的 Scheme獲取到輸入流
1 //圖片來源於Content provider 2 String contentprividerUrl = "content://media/external/audio/albumart/13"; 3 4 //圖片來源於assets 5 String assetsUrl = Scheme.ASSETS.wrap("image.png"); 6 7 //圖片來源於 8 String drawableUrl = Scheme.DRAWABLE.wrap("R.drawable.image");
1 listView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling)); 2 gridView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));
- 減少線程池中線程的個數,在ImageLoaderConfiguration中的(.threadPoolSize)中配置,推薦配置1-5
- 在DisplayImageOptions選項中配置bitmapConfig為Bitmap.Config.RGB_565,因為默認是ARGB_8888, 使用RGB_565會比使用ARGB_8888少消耗2倍的內存
- 在ImageLoaderConfiguration中配置圖片的內存緩存為memoryCache(new WeakMemoryCache()) 或者不使用內存緩存
- 在DisplayImageOptions選項中設置.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者imageScaleType(ImageScaleType.EXACTLY)
