珍惜作者劳动成果,如需转载,请注明出处。
http://blog.csdn.net/zhengzechuan91/article/details/50281835
Universal-Image-Loader (Github地址) 是一个优秀的图片加载开源项目,很多童鞋都在自己的项目中用到了。优秀的项目从来都是把简单留给开发者,把复杂封装在框架内部。ImageLoader作为Github上Star数过万的项目,备受开发者青睐,所以我们有必要搞清楚它的内部实现。
我们要研究一个框架,要顺着它的脉络去分析。先要搞清楚这个框架大概的思路是什么,这样我们才能顺着这个思路去对这个框架进行进一步的分析。
ImageLoader加载图片原理
首先来说说ImageLoader框架的整体思路:通过ImageLoader#displayImage()将Task加载到ImageLoaderEngine的线程池中,然后通过ImageDownloader缓存到Cache,再经过BitmapProcessor加工Bitmap,最后BitmapDisplayer显示Bitmap。
ImageLoader
ImageLoader类是一个单例,使用它之前首先要在应用的Application里调用ImageLoader#init(ImageLoaderConfiguration configuration)方法初始化,这个方法是配置自定义的ImageLoaderConfiguration,并实例化ImageLoaderEngine。
/* ImageLoader.java */
public synchronized void init(ImageLoaderConfiguration configuration) {
engine = new ImageLoaderEngine(configuration);
this.configuration = configuration;
}
而ImageLoaderEngine构造方法如下:
/* ImageLoaderEngine.java */
ImageLoaderEngine(ImageLoaderConfiguration configuration) {
this.configuration = configuration;
taskExecutor = configuration.taskExecutor;
taskExecutorForCachedImages = configuration.taskExecutorForCachedImages;
taskDistributor = DefaultConfigurationFactory.createTaskDistributor();
}
ImageLoaderEngine中有3个线程池:
taskDistributor使用了Executors#newCachedThreadPool(),
负责加载跟图片无关的任务;如果是首次加载图片,使用taskExecutor。
而如果是缓存过的图片,使用taskExecutorForCachedImages执行图片相关任务;
接下来先来看看一些配置相关的类:
DisplayImageOptions默认配置
首先是用于显示图片的配置类DisplayImageOptions,这里用到了Build模式,内部类Builder的默认值如下:
/* DisplayImageOptions$Builder.java */
//默认加载过程中的默认图都为空,需要手动配置
private int imageResOnLoading = 0;
private int imageResForEmptyUri = 0;
private int imageResOnFail = 0;
private Drawable imageOnLoading = null;
private Drawable imageForEmptyUri = null;
private Drawable imageOnFail = null;
//默认加载前不需要重置ImageViewAware
private boolean resetViewBeforeLoading = false;
//默认不缓存在内存中,需要手动配置
private boolean cacheInMemory = false;
//默认不缓存在磁盘上,需要手动配置
private boolean cacheOnDisk = false;
//默认Image的ScaleType为IN_SAMPLE_POWER_OF_2,在
//BaseImageDecoder#decode()时使用
//prepareDecodingOptions()方法对尺寸做处理时用到
private ImageScaleType imageScaleType = ImageScaleType.IN_SAMPLE_POWER_OF_2;
private Options decodingOptions = new Options();
//默认加载前无延时
private int delayBeforeLoading = 0;
//默认不接收EXIF参数
private boolean considerExifParams = false;
//下载参数
private Object extraForDownloader = null;
//缓存前处理
private BitmapProcessor preProcessor = null;
//缓存后处理
private BitmapProcessor postProcessor = null;
//默认显示图片为SimpleBitmapDisplayer,实现了display()
//方法,通过给imageAware使用setImageBitmap(bitmap)方法
//显示图片。
private BitmapDisplayer displayer = DefaultConfigurationFactory.createBitmapDisplayer();
//Handler
private Handler handler = null;
//默认为异步加载
private boolean isSyncLoading = false;
ImageLoaderConfiguration默认配置
另一个类为用于图片加载缓存的配置类ImageLoaderConfiguration,还是使用的Build模式,默认值如下:
/* ImageLoaderConfiguration$Builder.java */
private Context context;
//图片内存缓存的宽度
private int maxImageWidthForMemoryCache = 0;
//图片内存缓存的高度
private int maxImageHeightForMemoryCache = 0;
//图片磁盘缓存的宽度
private int maxImageWidthForDiskCache = 0;
//图片磁盘缓存的高度
private int maxImageHeightForDiskCache = 0;
//默认磁盘缓存不处理图片
private BitmapProcessor processorForDiskCache = null;
private Executor taskExecutor = null;
private Executor taskExecutorForCachedImages = null;
private boolean customExecutor = false;
private boolean customExecutorForCachedImages = false;
//默认的线程池容量为3
private int threadPoolSize = DEFAULT_THREAD_POOL_SIZE;
//默认线程优先级为3,正常为5
private int threadPriority = DEFAULT_THREAD_PRIORITY;
//默认同一Uri的图片在内存中可以有多个尺寸
private boolean</