Android图片加载开源框架Universal-Image-Loader解析

g4yy 9年前

1.UIL原理

a.UI:请求数据,使用唯一的Key值索引Memory Cache中的Bitmap。

b.内存缓存:缓存搜索,如果能找到Key值对应的Bitmap,则返回数据。否则执行c

c.硬盘存储:使用唯一Key值对应的文件名,检索SDCard上的文件。如果有对应文件,使用BitmapFactory.decode*方法,解码Bitmap并返回数据,同时将数据写入缓存。如果没有对应文件,执行d。

d.下载图片:启动异步线程,从数据源下载数据(Web)。

e.若下载成功,将数据同时写入硬盘和缓存,并将Bitmap显示在UI中。


2.UIL特征


多线程下载图片

随意配置ImageLoader

支持二级缓存

支持加载文件系统,assets,drawable等图片

支持图片下载过程的监听

。。。

特征很多,这里就不一一列举了


3.UIL解析

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

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

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


4.ImageLoaderConfiguration配置


  ImageLoaderConfiguration configuration=ImageLoaderConfiguration.createDefault(this);
                                            <span style="font-family: 微软雅黑, 宋体, Arial;">ImageLoader.getInstance().init(configuration);</span>


使用createDefault()方法创建了一个默认的ImageLoaderConfifuration

1.开启内存缓存,压缩的图片大小为屏幕的宽和高

2.开启硬盘缓存,不压缩图片

3.默认的线程池为3

4.允许缓存不同尺寸的图片

5.默认使用FIFO处理任务

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)
以上对应默认配置,如果默认配置不满足你的要求,可以自行修改


5.DisplayImageOptions配置(根据需求自行修改


DisplayImageOptions options = new DisplayImageOptions.Builder()          .showImageOnLoading(R.drawable.ic) // 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


1.根据网络情况设置图片状态(空白,下载错误,正在下载)

2.图片加载完成后是否重置view

3.设置下载延迟时间

4.是否缓存到内存或者硬盘

5.下载完成后对图片的处理


6.ImageLoader


ImageLoader有两个具体的方法,loadImage()和displayImage(),在项目中一般直接使用displayImage()方法,比较方便


ImageLoader.getInstance().displayImage(imageUrl, mImageView, options);

7.加载其他来源的图片


加载其他来源的图片时,只需要把url改掉

加载content provider图片String contentprividerUrl = “content://media/external/audio/albumart/13"

加载assets图片String assetsUrl = Scheme.ASSETS.wrap("image.png");  

加载drawable图片String drawableUrl = Scheme.DRAWABLE.wrap("R.drawable.image")


8.UIL内存缓存策略


1. 只使用的是强引用缓存 

LruMemoryCache(这个类就是这个开源框架默认的内存缓存类,缓存的是bitmap的强引用,下面我会从源码上面分析这个类)

  2.使用强引用和弱引用相结合的缓存有

  UsingFreqLimitedMemoryCache(如果缓存的图片总量超过限定值,先删除使用频率最小的bitmap)

LRULimitedMemoryCache(这个也是使用的lru算法,和LruMemoryCache不同的是,他缓存的是bitmap的弱引用)

FIFOLimitedMemoryCache(先进先出的缓存策略,当超过设定值,先删除最先加入缓存的bitmap)

LargestLimitedMemoryCache(当超过缓存限定值,先删除最大的bitmap对象)

LimitedAgeMemoryCache(当 bitmap加入缓存中的时间超过我们设定的值,将其删除)

  3.只使用弱引用缓存

  WeakMemoryCache(这个类缓存bitmap的总大小没有限制,唯一不足的地方就是不稳定,缓存的图片容易被回收掉)


9.UIL硬盘缓存策略


FileCountLimitedDiscCache(可以设定缓存图片的个数,当超过设定值,删除掉最先加入到硬盘的文件)LimitedAgeDiscCache(设定文件存活的最长时间,当超过这个值,就删除该文件)

TotalSizeLimitedDiscCache(设定缓存bitmap的最大值,当超过这个值,删除最先加入到硬盘的文件)

UnlimitedDiscCache(这个缓存类没有任何的限制)

注:UIL默认内存缓存使用的LruMemoryCache,默认硬盘缓存使用的是UnlimitedDiscCache



10.UIL如何避免OOM

1.减少线程池的个数,在ImageLoaderConfiguration中的(.threadPoolSize)中配置,默认为3

2.在DisplayImageOptions选项中配置bitmapConfig为Bitmap.Config.RGB_565,因为默认是ARGB_8888, 使用RGB_565会比使用ARGB_8888少消耗2倍的内存

3.在ImageLoaderConfiguration中配置图片的内存缓存为memoryCache(new WeakMemoryCache()) 或者不使用内存缓存

4.在DisplayImageOptions选项中设置.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者imageScaleType(ImageScaleType.EXACTLY)

来自:http://blog.csdn.net/elinavampire/article/details/46662213