Android-Universal-Image-Loader三大组件DisplayImageOptions、ImageLoader、ImageLoaderConfiguration详解

一、介绍

 Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。所以,如果你的程序里需要这个功能的话,那么不妨试试它。因为已经封装好了一些类和方法。我们 可以直接拿来用了。而不用重复去写了。其实,写一个这方面的程序还是比较麻烦的,要考虑多线程缓存,内存溢出等很多方面。

二、具体使用

一个好的类库的重要特征就是可配置性强。我们先简单使用Android-Universal-Image-Loader,一般情况下使用默认配置就可以了。

下面的实例利用Android-Universal-Image-Loader将网络图片加载到图片墙中。

 1 public class BaseActivity extends Activity {
 2     ImageLoader imageLoader;
 3     @Override
 4     protected void onCreate(Bundle savedInstanceState) {
 5           // Create global configuration and initialize ImageLoader with this configuration
 6         ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
 7             .build();
 8         ImageLoader.getInstance().init(config);
 9         super.onCreate(savedInstanceState);
10     }
11 }  
  1 public class MainActivity extends BaseActivity {
  2 
  3     @Override
  4     protected void onCreate(Bundle savedInstanceState) {
  5         super.onCreate(savedInstanceState);
  6         setContentView(R.layout.activity_main);
  7   
  8         ImageLoader imageLoader = ImageLoader.getInstance();
  9 
 10         GridView gridView = (GridView) this.findViewById(R.id.grdvImageWall);
 11         gridView.setAdapter(new PhotoWallAdapter(Constants.IMAGES));
 12     }
 13 
 14     static class ViewHolder {
 15         ImageView imageView;
 16         ProgressBar progressBar;
 17     }
 18 
 19     public class PhotoWallAdapter extends BaseAdapter {
 20         String[] imageUrls;
 21         ImageLoader imageLoad;
 22         DisplayImageOptions options;
 23         LinearLayout gridViewItem;
 24 
 25         public PhotoWallAdapter(String[] imageUrls) {
 26             assert imageUrls != null;
 27             this.imageUrls = imageUrls;
 28 
 29             options = new DisplayImageOptions.Builder()
 30                     .showImageOnLoading(R.drawable.ic_stub) // resource or
 31                                                             // drawable
 32                     .showImageForEmptyUri(R.drawable.ic_empty) // resource or
 33                                                                 // drawable
 34                     .showImageOnFail(R.drawable.ic_error) // resource or
 35                                                             // drawable
 36                     .resetViewBeforeLoading(false) // default
 37                     .delayBeforeLoading(1000).cacheInMemory(false) // default
 38                     .cacheOnDisk(false) // default
 39                     .considerExifParams(false) // default
 40                     .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default
 41                     .bitmapConfig(Bitmap.Config.ARGB_8888) // default
 42                     .displayer(new SimpleBitmapDisplayer()) // default
 43                     .handler(new Handler()) // default
 44                     .build();
 45             this.imageLoad = ImageLoader.getInstance();
 46 
 47         }
 48 
 49         @Override
 50         public int getCount() {
 51             return this.imageUrls.length;
 52         }
 53 
 54         @Override
 55         public Object getItem(int position) {
 56             if (position <= 0 || position >= this.imageUrls.length) {
 57                 throw new IllegalArgumentException(
 58                         "position<=0||position>=this.imageUrls.length");
 59             }
 60             return this.imageUrls[position];
 61         }
 62 
 63         @Override
 64         public long getItemId(int position) {
 65             return position;
 66         }
 67 
 68         @Override
 69         public View getView(int position, View convertView, ViewGroup parent) {
 70             // 判断这个image是否已经在缓存当中,如果没有就下载
 71             final ViewHolder holder;
 72             if (convertView == null) {
 73                 holder = new ViewHolder();
 74                 gridViewItem = (LinearLayout) getLayoutInflater().inflate(
 75                         R.layout.image_wall_item, null);
 76                 holder.imageView = (ImageView) gridViewItem
 77                         .findViewById(R.id.item_image);
 78                 holder.progressBar = (ProgressBar) gridViewItem
 79                         .findViewById(R.id.item_process);
 80                 gridViewItem.setTag(holder);
 81                 convertView = gridViewItem;
 82             } else {
 83                 holder = (ViewHolder) gridViewItem.getTag();
 84             }
 85             this.imageLoad.displayImage(this.imageUrls[position],
 86                     holder.imageView, options,
 87                     new SimpleImageLoadingListener() {
 88 
 89                         @Override
 90                         public void onLoadingStarted(String imageUri, View view) {
 91                             holder.progressBar.setProgress(0);
 92                             holder.progressBar.setVisibility(View.VISIBLE);
 93                         }
 94 
 95                         @Override
 96                         public void onLoadingFailed(String imageUri, View view,
 97                                 FailReason failReason) {
 98                             holder.progressBar.setVisibility(View.GONE);
 99                         }
100 
101                         @Override
102                         public void onLoadingComplete(String imageUri,
103                                 View view, Bitmap loadedImage) {
104                             holder.progressBar.setVisibility(View.GONE);
105                         }
106 
107                     }, new ImageLoadingProgressListener() {
108 
109                         @Override
110                         public void onProgressUpdate(String imageUri,
111                                 View view, int current, int total) {
112                             holder.progressBar.setProgress(Math.round(100.0f
113                                     * current / total));
114                         }
115                     }); // 通过URL判断图片是否已经下载
116             return convertView;
117         }
118 
119     }
120 }

里面主要的对象都用        突出显示了。

三者的关系

ImageLoaderConfiguration是针对图片缓存的全局配置,主要有线程类、缓存大小、磁盘大小、图片下载与解析、日志方面的配置。

ImageLoader是具体下载图片,缓存图片,显示图片的具体执行类,它有两个具体的方法displayImage(...)、loadImage(...),但是其实最终他们的实现都是displayImage(...)。

DisplayImageOptions用于指导每一个Imageloader根据网络图片的状态(空白、下载错误、正在下载)显示对应的图片,是否将缓存加载到磁盘上,下载完后对图片进行怎么样的处理。

从三者的协作关系上看,他们有点像厨房规定、厨师、客户个人口味之间的关系。ImageLoaderConfiguration就像是厨房里面的规定,每一个厨师要怎么着装,要怎么保持厨房的干净,这是针对每一个厨师都适用的规定,而且不允许个性化改变。ImageLoader就像是具体做菜的厨师,负责具体菜谱的制作。DisplayImageOptions就像每个客户的偏好,根据客户是重口味还是清淡,每一个imageLoader根据DisplayImageOptions的要求具体执行。

 

ImageLoaderConfiguration

在上面的示例代码中,我们使用ImageLoaderConfiguration的默认配置,下面给出ImageLoaderConfiguration比较详尽的配置,从下面的配置中,可以看出ImageLoaderConfiguration的配置主要是全局性的配置,主要有线程类、缓存大小、磁盘大小、图片下载与解析、日志方面的配置。

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
        .memoryCacheExtraOptions(480, 800) // default = device screen dimensions
        .diskCacheExtraOptions(480, 800, null)
        .taskExecutor(...)
        .taskExecutorForCachedImages(...)
        .threadPoolSize(3) // default
        .threadPriority(Thread.NORM_PRIORITY - 1) // default
        .tasksProcessingOrder(QueueProcessingType.FIFO) // default
        .denyCacheImageMultipleSizesInMemory()
        .memoryCache(new LruMemoryCache(2 * 1024 * 1024))
        .memoryCacheSize(2 * 1024 * 1024)
        .memoryCacheSizePercentage(13) // default
        .diskCache(new UnlimitedDiscCache(cacheDir)) // default
        .diskCacheSize(50 * 1024 * 1024)
        .diskCacheFileCount(100)
        .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
        .imageDownloader(new BaseImageDownloader(context)) // default
        .imageDecoder(new BaseImageDecoder()) // default
        .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
        .writeDebugLogs()
        .build();

ImageLoaderConfiguration的主要职责就是记录相关的配置,它的内部其实就是一些字段的集合(如下面的源代码)。它有一个builder的内部类,这个类中的字段跟ImageLoaderConfiguration中的字段完全一致,它有一些默认值,通过修改builder可以配置ImageLoaderConfiguration。

  1 /*******************************************************************************
  2  * Copyright 2011-2013 Sergey Tarasevich
  3  *
  4  * Licensed under the Apache License, Version 2.0 (the "License");
  5  * you may not use this file except in compliance with the License.
  6  * You may obtain a copy of the License at
  7  *
  8  * http://www.apache.org/licenses/LICENSE-2.0
  9  *
 10  * Unless required by applicable law or agreed to in writing, software
 11  * distributed under the License is distributed on an "AS IS" BASIS,
 12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  * See the License for the specific language governing permissions and
 14  * limitations under the License.
 15  *******************************************************************************/
 16 package com.nostra13.universalimageloader.core;
 17 
 18 import android.content.Context;
 19 import android.content.res.Resources;
 20 import android.util.DisplayMetrics;
 21 import com.nostra13.universalimageloader.cache.disc.DiskCache;
 22 import com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator;
 23 import com.nostra13.universalimageloader.cache.memory.MemoryCache;
 24 import com.nostra13.universalimageloader.cache.memory.impl.FuzzyKeyMemoryCache;
 25 import com.nostra13.universalimageloader.core.assist.FlushedInputStream;
 26 import com.nostra13.universalimageloader.core.assist.ImageSize;
 27 import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
 28 import com.nostra13.universalimageloader.core.decode.ImageDecoder;
 29 import com.nostra13.universalimageloader.core.download.ImageDownloader;
 30 import com.nostra13.universalimageloader.core.process.BitmapProcessor;
 31 import com.nostra13.universalimageloader.utils.L;
 32 import com.nostra13.universalimageloader.utils.MemoryCacheUtils;
 33 
 34 import java.io.IOException;
 35 import java.io.InputStream;
 36 import java.util.concurrent.Executor;
 37 
 38 /**
 39  * Presents configuration for {@link ImageLoader}
 40  *
 41  * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
 42  * @see ImageLoader
 43  * @see MemoryCache
 44  * @see DiskCache
 45  * @see DisplayImageOptions
 46  * @see ImageDownloader
 47  * @see FileNameGenerator
 48  * @since 1.0.0
 49  */
 50 public final class ImageLoaderConfiguration {
 51 
 52     final Resources resources;
 53 
 54     final int maxImageWidthForMemoryCache;
 55     final int maxImageHeightForMemoryCache;
 56     final int maxImageWidthForDiskCache;
 57     final int maxImageHeightForDiskCache;
 58     final BitmapProcessor processorForDiskCache;
 59 
 60     final Executor taskExecutor;
 61     final Executor taskExecutorForCachedImages;
 62     final boolean customExecutor;
 63     final boolean customExecutorForCachedImages;
 64 
 65     final int threadPoolSize;
 66     final int threadPriority;
 67     final QueueProcessingType tasksProcessingType;
 68 
 69     final MemoryCache memoryCache;
 70     final DiskCache diskCache;
 71     final ImageDownloader downloader;
 72     final ImageDecoder decoder;
 73     final DisplayImageOptions defaultDisplayImageOptions;
 74 
 75     final ImageDownloader networkDeniedDownloader;
 76     final ImageDownloader slowNetworkDownloader;
 77 
 78     private ImageLoaderConfiguration(final Builder builder) {
 79         resources = builder.context.getResources();
 80         maxImageWidthForMemoryCache = builder.maxImageWidthForMemoryCache;
 81         maxImageHeightForMemoryCache = builder.maxImageHeightForMemoryCache;
 82         maxImageWidthForDiskCache = builder.maxImageWidthForDiskCache;
 83         maxImageHeightForDiskCache = builder.maxImageHeightForDiskCache;
 84         processorForDiskCache = builder.processorForDiskCache;
 85         taskExecutor = builder.taskExecutor;
 86         taskExecutorForCachedImages = builder.taskExecutorForCachedImages;
 87         threadPoolSize = builder.threadPoolSize;
 88         threadPriority = builder.threadPriority;
 89         tasksProcessingType = builder.tasksProcessingType;
 90         diskCache = builder.diskCache;
 91         memoryCache = builder.memoryCache;
 92         defaultDisplayImageOptions = builder.defaultDisplayImageOptions;
 93         downloader = builder.downloader;
 94         decoder = builder.decoder;
 95 
 96         customExecutor = builder.customExecutor;
 97         customExecutorForCachedImages = builder.customExecutorForCachedImages;
 98 
 99         networkDeniedDownloader = new NetworkDeniedImageDownloader(downloader);
100         slowNetworkDownloader = new SlowNetworkImageDownloader(downloader);
101 
102         L.writeDebugLogs(builder.writeLogs);
103     }
104 
105     /**
106      * Creates default configuration for {@link ImageLoader} <br />
107      * <b>Default values:</b>
108      * <ul>
109      * <li>maxImageWidthForMemoryCache = device's screen width</li>
110      * <li>maxImageHeightForMemoryCache = device's screen height</li>
111      * <li>maxImageWidthForDikcCache = unlimited</li>
112      * <li>maxImageHeightForDiskCache = unlimited</li>
113      * <li>threadPoolSize = {@link Builder#DEFAULT_THREAD_POOL_SIZE this}</li>
114      * <li>threadPriority = {@link Builder#DEFAULT_THREAD_PRIORITY this}</li>
115      * <li>allow to cache different sizes of image in memory</li>
116      * <li>memoryCache = {@link DefaultConfigurationFactory#createMemoryCache(int)}</li>
117      * <li>diskCache = {@link com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache}</li>
118      * <li>imageDownloader = {@link DefaultConfigurationFactory#createImageDownloader(Context)}</li>
119      * <li>imageDecoder = {@link DefaultConfigurationFactory#createImageDecoder(boolean)}</li>
120      * <li>diskCacheFileNameGenerator = {@link DefaultConfigurationFactory#createFileNameGenerator()}</li>
121      * <li>defaultDisplayImageOptions = {@link DisplayImageOptions#createSimple() Simple options}</li>
122      * <li>tasksProcessingOrder = {@link QueueProcessingType#FIFO}</li>
123      * <li>detailed logging disabled</li>
124      * </ul>
125      */
126     public static ImageLoaderConfiguration createDefault(Context context) {
127         return new Builder(context).build();
128     }
129 
130     ImageSize getMaxImageSize() {
131         DisplayMetrics displayMetrics = resources.getDisplayMetrics();
132 
133         int width = maxImageWidthForMemoryCache;
134         if (width <= 0) {
135             width = displayMetrics.widthPixels;
136         }
137         int height = maxImageHeightForMemoryCache;
138         if (height <= 0) {
139             height = displayMetrics.heightPixels;
140         }
141         return new ImageSize(width, height);
142     }
143 
144     /**
145      * Builder for {@link ImageLoaderConfiguration}
146      *
147      * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
148      */
149     public static class Builder {
150 
151         private static final String WARNING_OVERLAP_DISK_CACHE_PARAMS = "diskCache(), diskCacheSize() and diskCacheFileCount calls overlap each other";
152         private static final String WARNING_OVERLAP_DISK_CACHE_NAME_GENERATOR = "diskCache() and diskCacheFileNameGenerator() calls overlap each other";
153         private static final String WARNING_OVERLAP_MEMORY_CACHE = "memoryCache() and memoryCacheSize() calls overlap each other";
154         private static final String WARNING_OVERLAP_EXECUTOR = "threadPoolSize(), threadPriority() and tasksProcessingOrder() calls "
155                 + "can overlap taskExecutor() and taskExecutorForCachedImages() calls.";
156 
157         /** {@value} */
158         public static final int DEFAULT_THREAD_POOL_SIZE = 3;
159         /** {@value} */
160         public static final int DEFAULT_THREAD_PRIORITY = Thread.NORM_PRIORITY - 1;
161         /** {@value} */
162         public static final QueueProcessingType DEFAULT_TASK_PROCESSING_TYPE = QueueProcessingType.FIFO;
163 
164         private Context context;
165 
166         private int maxImageWidthForMemoryCache = 0;
167         private int maxImageHeightForMemoryCache = 0;
168         private int maxImageWidthForDiskCache = 0;
169         private int maxImageHeightForDiskCache = 0;
170         private BitmapProcessor processorForDiskCache = null;
171 
172         private Executor taskExecutor = null;
173         private Executor taskExecutorForCachedImages = null;
174         private boolean customExecutor = false;
175         private boolean customExecutorForCachedImages = false;
176 
177         private int threadPoolSize = DEFAULT_THREAD_POOL_SIZE;
178         private int threadPriority = DEFAULT_THREAD_PRIORITY;
179         private boolean denyCacheImageMultipleSizesInMemory = false;
180         private QueueProcessingType tasksProcessingType = DEFAULT_TASK_PROCESSING_TYPE;
181 
182         private int memoryCacheSize = 0;
183         private long diskCacheSize = 0;
184         private int diskCacheFileCount = 0;
185 
186         private MemoryCache memoryCache = null;
187         private DiskCache diskCache = null;
188         private FileNameGenerator diskCacheFileNameGenerator = null;
189         private ImageDownloader downloader = null;
190         private ImageDecoder decoder;
191         private DisplayImageOptions defaultDisplayImageOptions = null;
192 
193         private boolean writeLogs = false;
194 
195         public Builder(Context context) {
196             this.context = context.getApplicationContext();
197         }
198 
199         /**
200          * Sets options for memory cache
201          *
202          * @param maxImageWidthForMemoryCache  Maximum image width which will be used for memory saving during decoding
203          *                                     an image to {@link android.graphics.Bitmap Bitmap}. <b>Default value - device's screen width</b>
204          * @param maxImageHeightForMemoryCache Maximum image height which will be used for memory saving during decoding
205          *                                     an image to {@link android.graphics.Bitmap Bitmap}. <b>Default value</b> - device's screen height
206          */
207         public Builder memoryCacheExtraOptions(int maxImageWidthForMemoryCache, int maxImageHeightForMemoryCache) {
208             this.maxImageWidthForMemoryCache = maxImageWidthForMemoryCache;
209             this.maxImageHeightForMemoryCache = maxImageHeightForMemoryCache;
210             return this;
211         }
212 
213         /**
214          * @deprecated Use
215          * {@link #diskCacheExtraOptions(int, int, com.nostra13.universalimageloader.core.process.BitmapProcessor)}
216          * instead
217          */
218         @Deprecated
219         public Builder discCacheExtraOptions(int maxImageWidthForDiskCache, int maxImageHeightForDiskCache,
220                 BitmapProcessor processorForDiskCache) {
221             return diskCacheExtraOptions(maxImageWidthForDiskCache, maxImageHeightForDiskCache, processorForDiskCache);
222         }
223 
224         /**
225          * Sets options for resizing/compressing of downloaded images before saving to disk cache.<br />
226          * <b>NOTE: Use this option only when you have appropriate needs. It can make ImageLoader slower.</b>
227          *
228          * @param maxImageWidthForDiskCache  Maximum width of downloaded images for saving at disk cache
229          * @param maxImageHeightForDiskCache Maximum height of downloaded images for saving at disk cache
230          * @param processorForDiskCache      null-ok; {@linkplain BitmapProcessor Bitmap processor} which process images before saving them in disc cache
231          */
232         public Builder diskCacheExtraOptions(int maxImageWidthForDiskCache, int maxImageHeightForDiskCache,
233                 BitmapProcessor processorForDiskCache) {
234             this.maxImageWidthForDiskCache = maxImageWidthForDiskCache;
235             this.maxImageHeightForDiskCache = maxImageHeightForDiskCache;
236             this.processorForDiskCache = processorForDiskCache;
237             return this;
238         }
239 
240         /**
241          * Sets custom {@linkplain Executor executor} for tasks of loading and displaying images.<br />
242          * <br />
243          * <b>NOTE:</b> If you set custom executor then following configuration options will not be considered for this
244          * executor:
245          * <ul>
246          * <li>{@link #threadPoolSize(int)}</li>
247          * <li>{@link #threadPriority(int)}</li>
248          * <li>{@link #tasksProcessingOrder(QueueProcessingType)}</li>
249          * </ul>
250          *
251          * @see #taskExecutorForCachedImages(Executor)
252          */
253         public Builder taskExecutor(Executor executor) {
254             if (threadPoolSize != DEFAULT_THREAD_POOL_SIZE || threadPriority != DEFAULT_THREAD_PRIORITY || tasksProcessingType != DEFAULT_TASK_PROCESSING_TYPE) {
255                 L.w(WARNING_OVERLAP_EXECUTOR);
256             }
257 
258             this.taskExecutor = executor;
259             return this;
260         }
261 
262         /**
263          * Sets custom {@linkplain Executor executor} for tasks of displaying <b>cached on disk</b> images (these tasks
264          * are executed quickly so UIL prefer to use separate executor for them).<br />
265          * <br />
266          * If you set the same executor for {@linkplain #taskExecutor(Executor) general tasks} and
267          * tasks about cached images (this method) then these tasks will be in the
268          * same thread pool. So short-lived tasks can wait a long time for their turn.<br />
269          * <br />
270          * <b>NOTE:</b> If you set custom executor then following configuration options will not be considered for this
271          * executor:
272          * <ul>
273          * <li>{@link #threadPoolSize(int)}</li>
274          * <li>{@link #threadPriority(int)}</li>
275          * <li>{@link #tasksProcessingOrder(QueueProcessingType)}</li>
276          * </ul>
277          *
278          * @see #taskExecutor(Executor)
279          */
280         public Builder taskExecutorForCachedImages(Executor executorForCachedImages) {
281             if (threadPoolSize != DEFAULT_THREAD_POOL_SIZE || threadPriority != DEFAULT_THREAD_PRIORITY || tasksProcessingType != DEFAULT_TASK_PROCESSING_TYPE) {
282                 L.w(WARNING_OVERLAP_EXECUTOR);
283             }
284 
285             this.taskExecutorForCachedImages = executorForCachedImages;
286             return this;
287         }
288 
289         /**
290          * Sets thread pool size for image display tasks.<br />
291          * Default value - {@link #DEFAULT_THREAD_POOL_SIZE this}
292          */
293         public Builder threadPoolSize(int threadPoolSize) {
294             if (taskExecutor != null || taskExecutorForCachedImages != null) {
295                 L.w(WARNING_OVERLAP_EXECUTOR);
296             }
297 
298             this.threadPoolSize = threadPoolSize;
299             return this;
300         }
301 
302         /**
303          * Sets the priority for image loading threads. Should be <b>NOT</b> greater than {@link Thread#MAX_PRIORITY} or
304          * less than {@link Thread#MIN_PRIORITY}<br />
305          * Default value - {@link #DEFAULT_THREAD_PRIORITY this}
306          */
307         public Builder threadPriority(int threadPriority) {
308             if (taskExecutor != null || taskExecutorForCachedImages != null) {
309                 L.w(WARNING_OVERLAP_EXECUTOR);
310             }
311 
312             if (threadPriority < Thread.MIN_PRIORITY) {
313                 this.threadPriority = Thread.MIN_PRIORITY;
314             } else {
315                 if (threadPriority > Thread.MAX_PRIORITY) {
316                     this.threadPriority = Thread.MAX_PRIORITY;
317                 } else {
318                     this.threadPriority = threadPriority;
319                 }
320             }
321             return this;
322         }
323 
324         /**
325          * When you display an image in a small {@link android.widget.ImageView ImageView} and later you try to display
326          * this image (from identical URI) in a larger {@link android.widget.ImageView ImageView} so decoded image of
327          * bigger size will be cached in memory as a previous decoded image of smaller size.<br />
328          * So <b>the default behavior is to allow to cache multiple sizes of one image in memory</b>. You can
329          * <b>deny</b> it by calling <b>this</b> method: so when some image will be cached in memory then previous
330          * cached size of this image (if it exists) will be removed from memory cache before.
331          */
332         public Builder denyCacheImageMultipleSizesInMemory() {
333             this.denyCacheImageMultipleSizesInMemory = true;
334             return this;
335         }
336 
337         /**
338          * Sets type of queue processing for tasks for loading and displaying images.<br />
339          * Default value - {@link QueueProcessingType#FIFO}
340          */
341         public Builder tasksProcessingOrder(QueueProcessingType tasksProcessingType) {
342             if (taskExecutor != null || taskExecutorForCachedImages != null) {
343                 L.w(WARNING_OVERLAP_EXECUTOR);
344             }
345 
346             this.tasksProcessingType = tasksProcessingType;
347             return this;
348         }
349 
350         /**
351          * Sets maximum memory cache size for {@link android.graphics.Bitmap bitmaps} (in bytes).<br />
352          * Default value - 1/8 of available app memory.<br />
353          * <b>NOTE:</b> If you use this method then
354          * {@link com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache LruMemoryCache} will be used as
355          * memory cache. You can use {@link #memoryCache(MemoryCache)} method to set your own implementation of
356          * {@link MemoryCache}.
357          */
358         public Builder memoryCacheSize(int memoryCacheSize) {
359             if (memoryCacheSize <= 0) throw new IllegalArgumentException("memoryCacheSize must be a positive number");
360 
361             if (memoryCache != null) {
362                 L.w(WARNING_OVERLAP_MEMORY_CACHE);
363             }
364 
365             this.memoryCacheSize = memoryCacheSize;
366             return this;
367         }
368 
369         /**
370          * Sets maximum memory cache size (in percent of available app memory) for {@link android.graphics.Bitmap
371          * bitmaps}.<br />
372          * Default value - 1/8 of available app memory.<br />
373          * <b>NOTE:</b> If you use this method then
374          * {@link com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache LruMemoryCache} will be used as
375          * memory cache. You can use {@link #memoryCache(MemoryCache)} method to set your own implementation of
376          * {@link MemoryCache}.
377          */
378         public Builder memoryCacheSizePercentage(int availableMemoryPercent) {
379             if (availableMemoryPercent <= 0 || availableMemoryPercent >= 100) {
380                 throw new IllegalArgumentException("availableMemoryPercent must be in range (0 < % < 100)");
381             }
382 
383             if (memoryCache != null) {
384                 L.w(WARNING_OVERLAP_MEMORY_CACHE);
385             }
386 
387             long availableMemory = Runtime.getRuntime().maxMemory();
388             memoryCacheSize = (int) (availableMemory * (availableMemoryPercent / 100f));
389             return this;
390         }
391 
392         /**
393          * Sets memory cache for {@link android.graphics.Bitmap bitmaps}.<br />
394          * Default value - {@link com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache LruMemoryCache}
395          * with limited memory cache size (size = 1/8 of available app memory)<br />
396          * <br />
397          * <b>NOTE:</b> If you set custom memory cache then following configuration option will not be considered:
398          * <ul>
399          * <li>{@link #memoryCacheSize(int)}</li>
400          * </ul>
401          */
402         public Builder memoryCache(MemoryCache memoryCache) {
403             if (memoryCacheSize != 0) {
404                 L.w(WARNING_OVERLAP_MEMORY_CACHE);
405             }
406 
407             this.memoryCache = memoryCache;
408             return this;
409         }
410 
411         /** @deprecated Use {@link #diskCacheSize(int)} instead */
412         @Deprecated
413         public Builder discCacheSize(int maxCacheSize) {
414             return diskCacheSize(maxCacheSize);
415         }
416 
417         /**
418          * Sets maximum disk cache size for images (in bytes).<br />
419          * By default: disk cache is unlimited.<br />
420          * <b>NOTE:</b> If you use this method then
421          * {@link com.nostra13.universalimageloader.cache.disc.impl.ext.LruDiscCache LruDiscCache}
422          * will be used as disk cache. You can use {@link #diskCache(DiskCache)} method for introduction your own
423          * implementation of {@link DiskCache}
424          */
425         public Builder diskCacheSize(int maxCacheSize) {
426             if (maxCacheSize <= 0) throw new IllegalArgumentException("maxCacheSize must be a positive number");
427 
428             if (diskCache != null) {
429                 L.w(WARNING_OVERLAP_DISK_CACHE_PARAMS);
430             }
431 
432             this.diskCacheSize = maxCacheSize;
433             return this;
434         }
435 
436         /** @deprecated Use {@link #diskCacheFileCount(int)} instead */
437         @Deprecated
438         public Builder discCacheFileCount(int maxFileCount) {
439             return diskCacheFileCount(maxFileCount);
440         }
441 
442         /**
443          * Sets maximum file count in disk cache directory.<br />
444          * By default: disk cache is unlimited.<br />
445          * <b>NOTE:</b> If you use this method then
446          * {@link com.nostra13.universalimageloader.cache.disc.impl.ext.LruDiscCache LruDiscCache}
447          * will be used as disk cache. You can use {@link #diskCache(DiskCache)} method for introduction your own
448          * implementation of {@link DiskCache}
449          */
450         public Builder diskCacheFileCount(int maxFileCount) {
451             if (maxFileCount <= 0) throw new IllegalArgumentException("maxFileCount must be a positive number");
452 
453             if (diskCache != null) {
454                 L.w(WARNING_OVERLAP_DISK_CACHE_PARAMS);
455             }
456 
457             this.diskCacheFileCount = maxFileCount;
458             return this;
459         }
460 
461         /** @deprecated Use {@link #diskCacheFileNameGenerator(com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator)} */
462         @Deprecated
463         public Builder discCacheFileNameGenerator(FileNameGenerator fileNameGenerator) {
464             return diskCacheFileNameGenerator(fileNameGenerator);
465         }
466 
467         /**
468          * Sets name generator for files cached in disk cache.<br />
469          * Default value -
470          * {@link com.nostra13.universalimageloader.core.DefaultConfigurationFactory#createFileNameGenerator()
471          * DefaultConfigurationFactory.createFileNameGenerator()}
472          */
473         public Builder diskCacheFileNameGenerator(FileNameGenerator fileNameGenerator) {
474             if (diskCache != null) {
475                 L.w(WARNING_OVERLAP_DISK_CACHE_NAME_GENERATOR);
476             }
477 
478             this.diskCacheFileNameGenerator = fileNameGenerator;
479             return this;
480         }
481 
482         /** @deprecated Use {@link #diskCache(com.nostra13.universalimageloader.cache.disc.DiskCache)} */
483         @Deprecated
484         public Builder discCache(DiskCache diskCache) {
485             return diskCache(diskCache);
486         }
487 
488         /**
489          * Sets disk cache for images.<br />
490          * Default value - {@link com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache
491          * BaseDiscCache}. Cache directory is defined by
492          * {@link com.nostra13.universalimageloader.utils.StorageUtils#getCacheDirectory(Context)
493          * StorageUtils.getCacheDirectory(Context)}.<br />
494          * <br />
495          * <b>NOTE:</b> If you set custom disk cache then following configuration option will not be considered:
496          * <ul>
497          * <li>{@link #diskCacheSize(int)}</li>
498          * <li>{@link #diskCacheFileCount(int)}</li>
499          * <li>{@link #diskCacheFileNameGenerator(FileNameGenerator)}</li>
500          * </ul>
501          */
502         public Builder diskCache(DiskCache diskCache) {
503             if (diskCacheSize > 0 || diskCacheFileCount > 0) {
504                 L.w(WARNING_OVERLAP_DISK_CACHE_PARAMS);
505             }
506             if (diskCacheFileNameGenerator != null) {
507                 L.w(WARNING_OVERLAP_DISK_CACHE_NAME_GENERATOR);
508             }
509 
510             this.diskCache = diskCache;
511             return this;
512         }
513 
514         /**
515          * Sets utility which will be responsible for downloading of image.<br />
516          * Default value -
517          * {@link com.nostra13.universalimageloader.core.DefaultConfigurationFactory#createImageDownloader(Context)
518          * DefaultConfigurationFactory.createImageDownloader()}
519          */
520         public Builder imageDownloader(ImageDownloader imageDownloader) {
521             this.downloader = imageDownloader;
522             return this;
523         }
524 
525         /**
526          * Sets utility which will be responsible for decoding of image stream.<br />
527          * Default value -
528          * {@link com.nostra13.universalimageloader.core.DefaultConfigurationFactory#createImageDecoder(boolean)
529          * DefaultConfigurationFactory.createImageDecoder()}
530          */
531         public Builder imageDecoder(ImageDecoder imageDecoder) {
532             this.decoder = imageDecoder;
533             return this;
534         }
535 
536         /**
537          * Sets default {@linkplain DisplayImageOptions display image options} for image displaying. These options will
538          * be used for every {@linkplain ImageLoader#displayImage(String, android.widget.ImageView) image display call}
539          * without passing custom {@linkplain DisplayImageOptions options}<br />
540          * Default value - {@link DisplayImageOptions#createSimple() Simple options}
541          */
542         public Builder defaultDisplayImageOptions(DisplayImageOptions defaultDisplayImageOptions) {
543             this.defaultDisplayImageOptions = defaultDisplayImageOptions;
544             return this;
545         }
546 
547         /**
548          * Enables detail logging of {@link ImageLoader} work. To prevent detail logs don't call this method.
549          * Consider {@link com.nostra13.universalimageloader.utils.L#disableLogging()} to disable
550          * ImageLoader logging completely (even error logs)
551          */
552         public Builder writeDebugLogs() {
553             this.writeLogs = true;
554             return this;
555         }
556 
557         /** Builds configured {@link ImageLoaderConfiguration} object */
558         public ImageLoaderConfiguration build() {
559             initEmptyFieldsWithDefaultValues();
560             return new ImageLoaderConfiguration(this);
561         }
562 
563         private void initEmptyFieldsWithDefaultValues() {
564             if (taskExecutor == null) {
565                 taskExecutor = DefaultConfigurationFactory
566                         .createExecutor(threadPoolSize, threadPriority, tasksProcessingType);
567             } else {
568                 customExecutor = true;
569             }
570             if (taskExecutorForCachedImages == null) {
571                 taskExecutorForCachedImages = DefaultConfigurationFactory
572                         .createExecutor(threadPoolSize, threadPriority, tasksProcessingType);
573             } else {
574                 customExecutorForCachedImages = true;
575             }
576             if (diskCache == null) {
577                 if (diskCacheFileNameGenerator == null) {
578                     diskCacheFileNameGenerator = DefaultConfigurationFactory.createFileNameGenerator();
579                 }
580                 diskCache = DefaultConfigurationFactory
581                         .createDiskCache(context, diskCacheFileNameGenerator, diskCacheSize, diskCacheFileCount);
582             }
583             if (memoryCache == null) {
584                 memoryCache = DefaultConfigurationFactory.createMemoryCache(memoryCacheSize);
585             }
586             if (denyCacheImageMultipleSizesInMemory) {
587                 memoryCache = new FuzzyKeyMemoryCache(memoryCache, MemoryCacheUtils.createFuzzyKeyComparator());
588             }
589             if (downloader == null) {
590                 downloader = DefaultConfigurationFactory.createImageDownloader(context);
591             }
592             if (decoder == null) {
593                 decoder = DefaultConfigurationFactory.createImageDecoder(writeLogs);
594             }
595             if (defaultDisplayImageOptions == null) {
596                 defaultDisplayImageOptions = DisplayImageOptions.createSimple();
597             }
598         }
599     }
600 
601     /**
602      * Decorator. Prevents downloads from network (throws {@link IllegalStateException exception}).<br />
603      * In most cases this downloader shouldn't be used directly.
604      *
605      * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
606      * @since 1.8.0
607      */
608     private static class NetworkDeniedImageDownloader implements ImageDownloader {
609 
610         private final ImageDownloader wrappedDownloader;
611 
612         public NetworkDeniedImageDownloader(ImageDownloader wrappedDownloader) {
613             this.wrappedDownloader = wrappedDownloader;
614         }
615 
616         @Override
617         public InputStream getStream(String imageUri, Object extra) throws IOException {
618             switch (Scheme.ofUri(imageUri)) {
619                 case HTTP:
620                 case HTTPS:
621                     throw new IllegalStateException();
622                 default:
623                     return wrappedDownloader.getStream(imageUri, extra);
624             }
625         }
626     }
627 
628     /**
629      * Decorator. Handles <a href="http://code.google.com/p/android/issues/detail?id=6066">this problem</a> on slow networks
630      * using {@link com.nostra13.universalimageloader.core.assist.FlushedInputStream}.
631      *
632      * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
633      * @since 1.8.1
634      */
635     private static class SlowNetworkImageDownloader implements ImageDownloader {
636 
637         private final ImageDownloader wrappedDownloader;
638 
639         public SlowNetworkImageDownloader(ImageDownloader wrappedDownloader) {
640             this.wrappedDownloader = wrappedDownloader;
641         }
642 
643         @Override
644         public InputStream getStream(String imageUri, Object extra) throws IOException {
645             InputStream imageStream = wrappedDownloader.getStream(imageUri, extra);
646             switch (Scheme.ofUri(imageUri)) {
647                 case HTTP:
648                 case HTTPS:
649                     return new FlushedInputStream(imageStream);
650                 default:
651                     return imageStream;
652             }
653         }
654     }
655 }
View Code

 

 Display Options

每一个ImageLoader.displayImage(...)都可以使用Display Options

DisplayImageOptions options = new DisplayImageOptions.Builder()
        .showImageOnLoading(R.drawable.ic_stub) // resource or drawable
        .showImageForEmptyUri(R.drawable.ic_empty) // resource or drawable
        .showImageOnFail(R.drawable.ic_error) // resource or drawable
        .resetViewBeforeLoading(false)  // default
        .delayBeforeLoading(1000)
        .cacheInMemory(false) // default
        .cacheOnDisk(false) // default
        .preProcessor(...)
        .postProcessor(...)
        .extraForDownloader(...)
        .considerExifParams(false) // default
        .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default
        .bitmapConfig(Bitmap.Config.ARGB_8888) // default
        .decodingOptions(...)
        .displayer(new SimpleBitmapDisplayer()) // default
        .handler(new Handler()) // default
        .build();

 Display Options的主要职责就是记录相关的配置,它的内部其实就是一些字段的集合(如下面的源代码)。它有一个builder的内部类,这个类中的字段跟DisplayOption中的字段完全一致,它有一些默认值,通过修改builder可以配置DisplayOptions。

  1 public final class DisplayImageOptions {
  2 
  3     private final int imageResOnLoading;
  4     private final int imageResForEmptyUri;
  5     private final int imageResOnFail;
  6     private final Drawable imageOnLoading;
  7     private final Drawable imageForEmptyUri;
  8     private final Drawable imageOnFail;
  9     private final boolean resetViewBeforeLoading;
 10     private final boolean cacheInMemory;
 11     private final boolean cacheOnDisk;
 12     private final ImageScaleType imageScaleType;
 13     private final Options decodingOptions;
 14     private final int delayBeforeLoading;
 15     private final boolean considerExifParams;
 16     private final Object extraForDownloader;
 17     private final BitmapProcessor preProcessor;
 18     private final BitmapProcessor postProcessor;
 19     private final BitmapDisplayer displayer;
 20     private final Handler handler;
 21     private final boolean isSyncLoading;
 22 
 23     private DisplayImageOptions(Builder builder) {
 24         imageResOnLoading = builder.imageResOnLoading;
 25         imageResForEmptyUri = builder.imageResForEmptyUri;
 26         imageResOnFail = builder.imageResOnFail;
 27         imageOnLoading = builder.imageOnLoading;
 28         imageForEmptyUri = builder.imageForEmptyUri;
 29         imageOnFail = builder.imageOnFail;
 30         resetViewBeforeLoading = builder.resetViewBeforeLoading;
 31         cacheInMemory = builder.cacheInMemory;
 32         cacheOnDisk = builder.cacheOnDisk;
 33         imageScaleType = builder.imageScaleType;
 34         decodingOptions = builder.decodingOptions;
 35         delayBeforeLoading = builder.delayBeforeLoading;
 36         considerExifParams = builder.considerExifParams;
 37         extraForDownloader = builder.extraForDownloader;
 38         preProcessor = builder.preProcessor;
 39         postProcessor = builder.postProcessor;
 40         displayer = builder.displayer;
 41         handler = builder.handler;
 42         isSyncLoading = builder.isSyncLoading;
 43     }
 44 
 45     public boolean shouldShowImageOnLoading() {
 46         return imageOnLoading != null || imageResOnLoading != 0;
 47     }
 48 
 49     public boolean shouldShowImageForEmptyUri() {
 50         return imageForEmptyUri != null || imageResForEmptyUri != 0;
 51     }
 52 
 53     public boolean shouldShowImageOnFail() {
 54         return imageOnFail != null || imageResOnFail != 0;
 55     }
 56 
 57     public boolean shouldPreProcess() {
 58         return preProcessor != null;
 59     }
 60 
 61     public boolean shouldPostProcess() {
 62         return postProcessor != null;
 63     }
 64 
 65     public boolean shouldDelayBeforeLoading() {
 66         return delayBeforeLoading > 0;
 67     }
 68 
 69     public Drawable getImageOnLoading(Resources res) {
 70         return imageResOnLoading != 0 ? res.getDrawable(imageResOnLoading) : imageOnLoading;
 71     }
 72 
 73     public Drawable getImageForEmptyUri(Resources res) {
 74         return imageResForEmptyUri != 0 ? res.getDrawable(imageResForEmptyUri) : imageForEmptyUri;
 75     }
 76 
 77     public Drawable getImageOnFail(Resources res) {
 78         return imageResOnFail != 0 ? res.getDrawable(imageResOnFail) : imageOnFail;
 79     }
 80 
 81     public boolean isResetViewBeforeLoading() {
 82         return resetViewBeforeLoading;
 83     }
 84 
 85     public boolean isCacheInMemory() {
 86         return cacheInMemory;
 87     }
 88 
 89     public boolean isCacheOnDisk() {
 90         return cacheOnDisk;
 91     }
 92 
 93     public ImageScaleType getImageScaleType() {
 94         return imageScaleType;
 95     }
 96 
 97     public Options getDecodingOptions() {
 98         return decodingOptions;
 99     }
100 
101     public int getDelayBeforeLoading() {
102         return delayBeforeLoading;
103     }
104 
105     public boolean isConsiderExifParams() {
106         return considerExifParams;
107     }
108 
109     public Object getExtraForDownloader() {
110         return extraForDownloader;
111     }
112 
113     public BitmapProcessor getPreProcessor() {
114         return preProcessor;
115     }
116 
117     public BitmapProcessor getPostProcessor() {
118         return postProcessor;
119     }
120 
121     public BitmapDisplayer getDisplayer() {
122         return displayer;
123     }
124 
125     public Handler getHandler() {
126         return handler;
127     }
128 
129     boolean isSyncLoading() {
130         return isSyncLoading;
131     }
132 
133     /**
134      * Builder for {@link DisplayImageOptions}
135      *
136      * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
137      */
138     public static class Builder {
139         private int imageResOnLoading = 0;
140         private int imageResForEmptyUri = 0;
141         private int imageResOnFail = 0;
142         private Drawable imageOnLoading = null;
143         private Drawable imageForEmptyUri = null;
144         private Drawable imageOnFail = null;
145         private boolean resetViewBeforeLoading = false;
146         private boolean cacheInMemory = false;
147         private boolean cacheOnDisk = false;
148         private ImageScaleType imageScaleType = ImageScaleType.IN_SAMPLE_POWER_OF_2;
149         private Options decodingOptions = new Options();
150         private int delayBeforeLoading = 0;
151         private boolean considerExifParams = false;
152         private Object extraForDownloader = null;
153         private BitmapProcessor preProcessor = null;
154         private BitmapProcessor postProcessor = null;
155         private BitmapDisplayer displayer = DefaultConfigurationFactory.createBitmapDisplayer();
156         private Handler handler = null;
157         private boolean isSyncLoading = false;
158 
159         public Builder() {
160             decodingOptions.inPurgeable = true;
161             decodingOptions.inInputShareable = true;
162         }
163 
164         /**
165          * Stub image will be displayed in {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
166          * image aware view} during image loading
167          *
168          * @param imageRes Stub image resource
169          * @deprecated Use {@link #showImageOnLoading(int)} instead
170          */
171         @Deprecated
172         public Builder showStubImage(int imageRes) {
173             imageResOnLoading = imageRes;
174             return this;
175         }
176 
177         /**
178          * Incoming image will be displayed in {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
179          * image aware view} during image loading
180          *
181          * @param imageRes Image resource
182          */
183         public Builder showImageOnLoading(int imageRes) {
184             imageResOnLoading = imageRes;
185             return this;
186         }
187 
188         /**
189          * Incoming drawable will be displayed in {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
190          * image aware view} during image loading.
191          * This option will be ignored if {@link DisplayImageOptions.Builder#showImageOnLoading(int)} is set.
192          */
193         public Builder showImageOnLoading(Drawable drawable) {
194             imageOnLoading = drawable;
195             return this;
196         }
197 
198         /**
199          * Incoming image will be displayed in {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
200          * image aware view} if empty URI (null or empty
201          * string) will be passed to <b>ImageLoader.displayImage(...)</b> method.
202          *
203          * @param imageRes Image resource
204          */
205         public Builder showImageForEmptyUri(int imageRes) {
206             imageResForEmptyUri = imageRes;
207             return this;
208         }
209 
210         /**
211          * Incoming drawable will be displayed in {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
212          * image aware view} if empty URI (null or empty
213          * string) will be passed to <b>ImageLoader.displayImage(...)</b> method.
214          * This option will be ignored if {@link DisplayImageOptions.Builder#showImageForEmptyUri(int)} is set.
215          */
216         public Builder showImageForEmptyUri(Drawable drawable) {
217             imageForEmptyUri = drawable;
218             return this;
219         }
220 
221         /**
222          * Incoming image will be displayed in {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
223          * image aware view} if some error occurs during
224          * requested image loading/decoding.
225          *
226          * @param imageRes Image resource
227          */
228         public Builder showImageOnFail(int imageRes) {
229             imageResOnFail = imageRes;
230             return this;
231         }
232 
233         /**
234          * Incoming drawable will be displayed in {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
235          * image aware view} if some error occurs during
236          * requested image loading/decoding.
237          * This option will be ignored if {@link DisplayImageOptions.Builder#showImageOnFail(int)} is set.
238          */
239         public Builder showImageOnFail(Drawable drawable) {
240             imageOnFail = drawable;
241             return this;
242         }
243 
244         /**
245          * {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
246          * image aware view} will be reset (set <b>null</b>) before image loading start
247          *
248          * @deprecated Use {@link #resetViewBeforeLoading(boolean) resetViewBeforeLoading(true)} instead
249          */
250         public Builder resetViewBeforeLoading() {
251             resetViewBeforeLoading = true;
252             return this;
253         }
254 
255         /**
256          * Sets whether {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
257          * image aware view} will be reset (set <b>null</b>) before image loading start
258          */
259         public Builder resetViewBeforeLoading(boolean resetViewBeforeLoading) {
260             this.resetViewBeforeLoading = resetViewBeforeLoading;
261             return this;
262         }
263 
264         /**
265          * Loaded image will be cached in memory
266          *
267          * @deprecated Use {@link #cacheInMemory(boolean) cacheInMemory(true)} instead
268          */
269         @Deprecated
270         public Builder cacheInMemory() {
271             cacheInMemory = true;
272             return this;
273         }
274 
275         /** Sets whether loaded image will be cached in memory */
276         public Builder cacheInMemory(boolean cacheInMemory) {
277             this.cacheInMemory = cacheInMemory;
278             return this;
279         }
280 
281         /**
282          * Loaded image will be cached on disk
283          *
284          * @deprecated Use {@link #cacheOnDisk(boolean) cacheOnDisk(true)} instead
285          */
286         @Deprecated
287         public Builder cacheOnDisc() {
288             return cacheOnDisk(true);
289         }
290 
291         /**
292          * Sets whether loaded image will be cached on disk
293          *
294          * @deprecated Use {@link #cacheOnDisk(boolean)} instead
295          */
296         @Deprecated
297         public Builder cacheOnDisc(boolean cacheOnDisk) {
298             return cacheOnDisk(cacheOnDisk);
299         }
300 
301         /** Sets whether loaded image will be cached on disk */
302         public Builder cacheOnDisk(boolean cacheOnDisk) {
303             this.cacheOnDisk = cacheOnDisk;
304             return this;
305         }
306 
307         /**
308          * Sets {@linkplain ImageScaleType scale type} for decoding image. This parameter is used while define scale
309          * size for decoding image to Bitmap. Default value - {@link ImageScaleType#IN_SAMPLE_POWER_OF_2}
310          */
311         public Builder imageScaleType(ImageScaleType imageScaleType) {
312             this.imageScaleType = imageScaleType;
313             return this;
314         }
315 
316         /** Sets {@link Bitmap.Config bitmap config} for image decoding. Default value - {@link Bitmap.Config#ARGB_8888} */
317         public Builder bitmapConfig(Bitmap.Config bitmapConfig) {
318             if (bitmapConfig == null) throw new IllegalArgumentException("bitmapConfig can't be null");
319             decodingOptions.inPreferredConfig = bitmapConfig;
320             return this;
321         }
322 
323         /**
324          * Sets options for image decoding.<br />
325          * <b>NOTE:</b> {@link Options#inSampleSize} of incoming options will <b>NOT</b> be considered. Library
326          * calculate the most appropriate sample size itself according yo {@link #imageScaleType(ImageScaleType)}
327          * options.<br />
328          * <b>NOTE:</b> This option overlaps {@link #bitmapConfig(android.graphics.Bitmap.Config) bitmapConfig()}
329          * option.
330          */
331         public Builder decodingOptions(Options decodingOptions) {
332             if (decodingOptions == null) throw new IllegalArgumentException("decodingOptions can't be null");
333             this.decodingOptions = decodingOptions;
334             return this;
335         }
336 
337         /** Sets delay time before starting loading task. Default - no delay. */
338         public Builder delayBeforeLoading(int delayInMillis) {
339             this.delayBeforeLoading = delayInMillis;
340             return this;
341         }
342 
343         /** Sets auxiliary object which will be passed to {@link ImageDownloader#getStream(String, Object)} */
344         public Builder extraForDownloader(Object extra) {
345             this.extraForDownloader = extra;
346             return this;
347         }
348 
349         /** Sets whether ImageLoader will consider EXIF parameters of JPEG image (rotate, flip) */
350         public Builder considerExifParams(boolean considerExifParams) {
351             this.considerExifParams = considerExifParams;
352             return this;
353         }
354 
355         /**
356          * Sets bitmap processor which will be process bitmaps before they will be cached in memory. So memory cache
357          * will contain bitmap processed by incoming preProcessor.<br />
358          * Image will be pre-processed even if caching in memory is disabled.
359          */
360         public Builder preProcessor(BitmapProcessor preProcessor) {
361             this.preProcessor = preProcessor;
362             return this;
363         }
364 
365         /**
366          * Sets bitmap processor which will be process bitmaps before they will be displayed in
367          * {@link com.nostra13.universalimageloader.core.imageaware.ImageAware image aware view} but
368          * after they'll have been saved in memory cache.
369          */
370         public Builder postProcessor(BitmapProcessor postProcessor) {
371             this.postProcessor = postProcessor;
372             return this;
373         }
374 
375         /**
376          * Sets custom {@link BitmapDisplayer displayer} for image loading task. Default value -
377          * {@link DefaultConfigurationFactory#createBitmapDisplayer()}
378          */
379         public Builder displayer(BitmapDisplayer displayer) {
380             if (displayer == null) throw new IllegalArgumentException("displayer can't be null");
381             this.displayer = displayer;
382             return this;
383         }
384 
385         Builder syncLoading(boolean isSyncLoading) {
386             this.isSyncLoading = isSyncLoading;
387             return this;
388         }
389 
390         /**
391          * Sets custom {@linkplain Handler handler} for displaying images and firing {@linkplain ImageLoadingListener
392          * listener} events.
393          */
394         public Builder handler(Handler handler) {
395             this.handler = handler;
396             return this;
397         }
398 
399         /** Sets all options equal to incoming options */
400         public Builder cloneFrom(DisplayImageOptions options) {
401             imageResOnLoading = options.imageResOnLoading;
402             imageResForEmptyUri = options.imageResForEmptyUri;
403             imageResOnFail = options.imageResOnFail;
404             imageOnLoading = options.imageOnLoading;
405             imageForEmptyUri = options.imageForEmptyUri;
406             imageOnFail = options.imageOnFail;
407             resetViewBeforeLoading = options.resetViewBeforeLoading;
408             cacheInMemory = options.cacheInMemory;
409             cacheOnDisk = options.cacheOnDisk;
410             imageScaleType = options.imageScaleType;
411             decodingOptions = options.decodingOptions;
412             delayBeforeLoading = options.delayBeforeLoading;
413             considerExifParams = options.considerExifParams;
414             extraForDownloader = options.extraForDownloader;
415             preProcessor = options.preProcessor;
416             postProcessor = options.postProcessor;
417             displayer = options.displayer;
418             handler = options.handler;
419             isSyncLoading = options.isSyncLoading;
420             return this;
421         }
422 
423         /** Builds configured {@link DisplayImageOptions} object */
424         public DisplayImageOptions build() {
425             return new DisplayImageOptions(this);
426         }
427     }
428 
429     /**
430      * Creates options appropriate for single displaying:
431      * <ul>
432      * <li>View will <b>not</b> be reset before loading</li>
433      * <li>Loaded image will <b>not</b> be cached in memory</li>
434      * <li>Loaded image will <b>not</b> be cached on disk</li>
435      * <li>{@link ImageScaleType#IN_SAMPLE_POWER_OF_2} decoding type will be used</li>
436      * <li>{@link Bitmap.Config#ARGB_8888} bitmap config will be used for image decoding</li>
437      * <li>{@link SimpleBitmapDisplayer} will be used for image displaying</li>
438      * </ul>
439      * <p/>
440      * These option are appropriate for simple single-use image (from drawables or from Internet) displaying.
441      */
442     public static DisplayImageOptions createSimple() {
443         return new Builder().build();
444     }
445 }
View Code

 

 

参考链接

http://blog.csdn.net/wangjinyu501/article/details/8091623

https://github.com/nostra13/Android-Universal-Image-Loader

http://www.intexsoft.com/blog/item/74-universal-image-loader-part-3.html

posted @ 2014-08-02 10:08  陈哈哈  阅读(70761)  评论(3编辑  收藏  举报