开源库universal-image-loader的学习

简介

UIL aims to provide a powerful, flexible and highly customizable instrument for image loading, caching and displaying. It provides a lot of configuration options and good control over the image loading and caching process.

uil_demo

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

特性
  1. 多线程下载图片,图片可以来源于网络,文件系统,项目文件夹assets中以及drawable中等
  2. 支持随意的配置ImageLoader,例如线程池,图片下载器,内存缓存策略,硬盘缓存策略,图片显示选项以及其他的一些配置
  3. 支持图片的内存缓存,文件系统缓存或者SD卡缓存
  4. 支持图片下载过程的监听
  5. 根据控件(ImageView)的大小对Bitmap进行裁剪,减少Bitmap占用过多的内存
  6. 较好的控制图片的加载过程,例如暂停图片加载,重新开始加载图片,一般使用 ListView,GridView中,滑动过程中暂停加载图片,停止滑动的时候去加载图片
  7. 提供在较慢的网络下对图片进行加载
流程图

the_flow_chart

使用步骤
uses-permission android:name="android.permission.INTERNET" />  
  1. 下载JAR包添加到工程libs目录下
  2. 配置Android Manifest文件

    <uses-permission android:name="android.permission.INTERNET" />  
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    
  3. 配置ImageLoaderConfiguration这个类实现全局ImageLoader,可以选择在Application中初始化设置该类

    ImageLoaderConfiguration config = new ImageLoaderConfiguration  
    .Builder(context)  
    .memoryCacheExtraOptions(480, 800) // max width, max height,即保存的每个缓存文件的最大长宽  
    .discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null) // Can slow ImageLoader, use it carefully (Better don't use it)/设置缓存的详细信息,最好不要设置这个  
    .threadPoolSize(3)//线程池内加载的数量  
    .threadPriority(Thread.NORM_PRIORITY - 2)  
    .denyCacheImageMultipleSizesInMemory()  
    .memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024)) // You can pass your own memory cache implementation/你可以通过自己的内存缓存实现  
    .memoryCacheSize(2 * 1024 * 1024)    
    .discCacheSize(50 * 1024 * 1024)    
    .discCacheFileNameGenerator(new Md5FileNameGenerator())//将保存的时候的URI名称用MD5 加密  
    .tasksProcessingOrder(QueueProcessingType.LIFO)  
    .discCacheFileCount(100) //缓存的文件数量  
    .discCache(new UnlimitedDiscCache(cacheDir))//自定义缓存路径  
    .defaultDisplayImageOptions(DisplayImageOptions.createSimple())  
    .imageDownloader(new BaseImageDownloader(context, 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超时时间  
    .writeDebugLogs() // Remove for release app  
    .build();//开始构建  
    

    以上的配置看个人需求进行选择,不是所有都要进行配置。
    配置好ImageLoaderConfiguration后,调用以下方法来实现初始化:

    ImageLoader.getInstance().init(config);//全局初始化此配置 
    
  4. 使用ImageLoader加载图片

    使用ImageLoader进行图片加载的时候,先要实例化ImageLoader,代码如下,建议放在基类Activity中,这样不必每次都去申明

    ImageLoader imageLoader = ImageLoader.getInstance(); 
    imageLoader.displayImage(...); 
    //一般用这个方法比较多
    imageLoader.displayImage(Stirng uri, ImageView imageView, DisplayImageOptions options );
    
ImageLoaderConfiguration、ImageLoader、DisplayImageOptions三者的关系

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

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

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

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

Acceptable URIs examples
String imageUri = "http://site.com/image.png"; // from Web
String imageUri = "file:///mnt/sdcard/image.png"; // from SD card
String imageUri = "content://media/external/audio/albumart/13"; // from content provider
String imageUri = "assets://image.png"; // from assets
String imageUri = "drawable://" + R.drawable.img; // from drawables (non-9patch images)
注意
  1. 上述提到的2个权限必须加入,否则会出错
  2. ImageLoaderConfiguration必须配置并且全局化的初始化这个配置ImageLoader.getInstance().init(config); 否则也会出现错误提示
  3. ImageLoader是根据ImageView的height,width确定图片的宽高。
  4. 如果经常出现OOM(别人那边看到的,觉得很有提的必要)

    • 减少配置之中线程池的大小,(.threadPoolSize).推荐1-5;
    • 使用.bitmapConfig(Bitmap.config.RGB_565)代替ARGB_8888;
    • 使用.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者 try.imageScaleType(ImageScaleType.EXACTLY);
    • 避免使用RoundedBitmapDisplayer.他会创建新的ARGB_8888格式的Bitmap对象;
    • 使用.memoryCache(new WeakMemoryCache()),不要使用.cacheInMemory();

参考链接

http://blog.csdn.net/vipzjyno1/article/details/23206387
http://www.cnblogs.com/kissazi2/p/3886563.html
http://blog.csdn.net/xiaanming/article/details/26810303