zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    [Other] 应用下载网站的APK/IPA等常见MIME设置
    [AIR] StageWebView可以和js通信
    [JavaScript] 判断设备类型,加载相应css
    [HTML] H5在webApp中的注意事项
    [JavaScript] css将footer置于页面最底部
    python 装饰器
    python while...else和for...else语法
    Linux haproxy配置参数
    Linux haproxy基础
    Linux ospf+lvs
  • 原文地址:https://www.cnblogs.com/kissazi2/p/3886563.html
Copyright © 2011-2022 走看看