Android-Universal-Image-Loader 图片加载库 详细分析
2014-11-04 17:46
501 查看
github地址:https://github.com/nostra13/Android-Universal-Image-Loader
· 再调用:ImageLoader.getInstance().init(config); 进行初始化
· 以上两步可放置在Application中 完成。
· 定义一个 DisplayImageOptions 对象,用于设定图片一些参数设定
· ImageLoader.getInstance().displayImage(); 用于加载uri所指向的图片到Image-Widget上,并提供加载过程的监听和加载进度的监听
构造函数私有,由Builder.builder()返回ImageLoaderConfiguration
static class Builder
在builder(){先调用了DefaultConfigurationFactory一系列方法,创建一些默认属性值给builder
然后再调用ImageLoaderConfiguration的构造函数传递builder对象过去 }
还有两个内部类,它们不需要手动注入,在LoadAndDisplayImageTask.getDownloader()中会自动选择使用普通loader还是以下两种:
NetworkDeniedImageDownloader 网络不可访问时的图片加载器, 如从本地加载
SlowNetworkImageDownloader 网络较慢时的图片加载器
createDiskCache(){有 : File individualCacheDir = StorageUtils.getIndividualCacheDirectory(context);
//设置了 缓存的目录 , 内问最后调用了StorageUtils.getCacheDirectory(),设置了/data/data/package/cache为缓存目录
}
StorageUtils.getOwnCacheDirectory() 设置自定义的缓存目录,它返回File对象;或者自定义一个File的目录。在配置时,调用
ImageLoaderConfiguration.diskCache(new DiskCache(cacheFile...));
interface DiscCache
abstract BaseDiscCache
LimitedAgeDiscCache extends BaseDiscCache 无限大小的缓存,分配了一个文件可缓存的时间long值,当取出缓存时,发现文件已超出缓存时间值,则删除缓存文件
UnlimitedDiscCache extends BaseDiscCache 无限大小的缓存,继承自BaseDiscCache未作改变
LruDiscCache 使用Lru算法的磁盘缓存,配置工厂中默认使用该缓存
interface MemoryCache
abstract BaseMemoryCache
LimitedMemoryCache extends BaseMemoryCache
WeakMemoryCache extends BaseMemoryCache
FuzzyKeyMemoryCache 在put()时,若放入的key即图片的uri,已存在于缓存中,那么先删除缓存中的记录,再进行put新的。
LimitedAgeMemoryCache
LruMemoryCache
publicenum Scheme {
HTTP("http"),HTTPS("https"),FILE("file"),CONTENT("content"),ASSETS("assets"),DRAWABLE("drawable"),UNKNOWN("");
} 定义了一个协议的enum。 在加载图片时,根据uri的前缀作不同的处理(选用不同的downLoader)。
enum 有一个wrap()和crop(),分别是加前缀和去前缀。
相应协议的加载方法:
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.image; // from drawables (only images, non-9patch)
void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom);//关于ImageAware,调用时传new ImageViewAware(imgview)就可
FadeInBitmapDisplayer 淡入动画显示
RoundedBitmapDisplayer 圆角显示
RoundedVignetteBitmapDisplayer 圆角显示,颜色会有个渐变的效果
SimpleBitmapDisplayer 简单实现
HashCodeFileNameGenerator 以imguri的hashcode为name
Md5FileNameGenerator 以imguri的md5值为name
SimpleImageLoadingListener 一个空实现, 不需要全部实现时,可以使用它。
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();
遇到的Bug:
用UIL加载res/drawable/ 固定资源id的图片,可能会造成图片显示的问题。
因为UIL会根据其id,也就是图片名字,作MD5命名,缓存在sdcard和memory中。
如果早期版本中已经缓存过某一id的图片,而新版本中对这个图片改了图片内容,那么就可能图片显示混乱了。
解决:在加载res/drawable中的图片时,DisplayImageOptions.Builder().cacheInMemory(false); 即不要在sdcard缓存
参考链接: http://blog.csdn.net/vipzjyno1/article/details/23206387
———————————————————————— updated on 2016-12-04 ————————————————————————
UIL作者,维护到1.9.5版后,就声明不再更新维护了。
因工作需要,使用了UIL,进行了一些源码重写,并提供工具类: https://github.com/aa86799/UILRevision
图片加载原理
示例程序中有个图片,很好的说明了图片加载的原理:使用流程
需要权限
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
初始化图片加载器 —— ImageLoader
· 先初始化图片加载的配置类:ImageLoaderConfiguration· 再调用:ImageLoader.getInstance().init(config); 进行初始化
· 以上两步可放置在Application中 完成。
加载并显示图片
在每个需要加载显示图片的地方,使用下列:· 定义一个 DisplayImageOptions 对象,用于设定图片一些参数设定
· ImageLoader.getInstance().displayImage(); 用于加载uri所指向的图片到Image-Widget上,并提供加载过程的监听和加载进度的监听
细节
ImageLoaderConfiguration
final Resources resources; final int maxImageWidthForMemoryCache; 内存缓存图片的最大宽度 final int maxImageHeightForMemoryCache; 内存缓存图片的最大高度 final int maxImageWidthForDiskCache; 磁盘缓存图片的宽度 final int maxImageHeightForDiskCache; 磁盘缓存图片的高度 final BitmapProcessor processorForDiskCache; 磁盘缓存图片处理器 final Executor taskExecutor; final Executor taskExecutorForCachedImages; 缓存任务线程池 final boolean customExecutor; final boolean customExecutorForCachedImages; 自定义缓存线程池 final int threadPoolSize; 池里核心线程数 final int threadPriority; 线程优先级 final QueueProcessingType tasksProcessingType; 任务队列的类型:enum{LIFO、FIFO} final MemoryCache memoryCache; 内存缓存 final DiskCache diskCache; 磁盘缓存 final ImageDownloader downloader; 图片下载器 final ImageDecoder decoder; 图片解析器 final DisplayImageOptions defaultDisplayImageOptions; 图片显示参数 final ImageDownloader networkDeniedDownloader; 图片下载器:禁止从网络加载 final ImageDownloader slowNetworkDownloader; 图片下载器:慢速网络加载
构造函数私有,由Builder.builder()返回ImageLoaderConfiguration
static class Builder
在builder(){先调用了DefaultConfigurationFactory一系列方法,创建一些默认属性值给builder
然后再调用ImageLoaderConfiguration的构造函数传递builder对象过去 }
还有两个内部类,它们不需要手动注入,在LoadAndDisplayImageTask.getDownloader()中会自动选择使用普通loader还是以下两种:
NetworkDeniedImageDownloader 网络不可访问时的图片加载器, 如从本地加载
SlowNetworkImageDownloader 网络较慢时的图片加载器
DefaultConfigurationFactory
用于创建一些默认的配置,如在build ImageLoaderConfiguration对象时,没有指定的,则由DefaultConfigurationFactory来创建。createDiskCache(){有 : File individualCacheDir = StorageUtils.getIndividualCacheDirectory(context);
//设置了 缓存的目录 , 内问最后调用了StorageUtils.getCacheDirectory(),设置了/data/data/package/cache为缓存目录
}
StorageUtils.getOwnCacheDirectory() 设置自定义的缓存目录,它返回File对象;或者自定义一个File的目录。在配置时,调用
ImageLoaderConfiguration.diskCache(new DiskCache(cacheFile...));
DiskCache 和 MemoryCache
都有一些默认的实现类interface DiscCache
abstract BaseDiscCache
LimitedAgeDiscCache extends BaseDiscCache 无限大小的缓存,分配了一个文件可缓存的时间long值,当取出缓存时,发现文件已超出缓存时间值,则删除缓存文件
UnlimitedDiscCache extends BaseDiscCache 无限大小的缓存,继承自BaseDiscCache未作改变
LruDiscCache 使用Lru算法的磁盘缓存,配置工厂中默认使用该缓存
interface MemoryCache
abstract BaseMemoryCache
LimitedMemoryCache extends BaseMemoryCache
WeakMemoryCache extends BaseMemoryCache
FuzzyKeyMemoryCache 在put()时,若放入的key即图片的uri,已存在于缓存中,那么先删除缓存中的记录,再进行put新的。
LimitedAgeMemoryCache
LruMemoryCache
DisplayImageOptions
也是由一个static Builder对象来生成private final int imageResOnLoading; 正在加载时显示的图片资源 id private final int imageResForEmptyUri; 图片uri为空时显示的图片 id private final int imageResOnFail; 图片加载失败显示的图片 id private final Drawable imageOnLoading; 正在加载时显示的图片资源 drawable private final Drawable imageForEmptyUri; 图片uri为空时显示的图片 drawable private final Drawable imageOnFail; 图片加载失败显示的图片 drawable private final boolean resetViewBeforeLoading; 加载前是否重置view private final boolean cacheInMemory; 是否启用内存缓存 private final boolean cacheOnDisk; 是否启用磁盘缓存 private final ImageScaleType imageScaleType; 图片缩放类型 private final Options decodingOptions; BitmapFactory用到的options private final int delayBeforeLoading; 延迟多久加载 private final boolean considerExifParams; exif参数是否可用 private final Object extraForDownloader; 额外的下载对象 private final BitmapProcessor preProcessor; bitmap加载前的处理 private final BitmapProcessor postProcessor; bitmap加载时的处理 private final BitmapDisplayer displayer; bitmap显示 private final Handler handler; private final boolean isSyncLoading; 是否同步加载图片(一个接一个的加载)
ImageDownloader
getStream(String imguri, obj); 从uri返回一个输入流publicenum Scheme {
HTTP("http"),HTTPS("https"),FILE("file"),CONTENT("content"),ASSETS("assets"),DRAWABLE("drawable"),UNKNOWN("");
} 定义了一个协议的enum。 在加载图片时,根据uri的前缀作不同的处理(选用不同的downLoader)。
enum 有一个wrap()和crop(),分别是加前缀和去前缀。
相应协议的加载方法:
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.image; // from drawables (only images, non-9patch)
BitmapDisplayer
这是一个接口, 有一个抽象的void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom);//关于ImageAware,调用时传new ImageViewAware(imgview)就可
FadeInBitmapDisplayer 淡入动画显示
RoundedBitmapDisplayer 圆角显示
RoundedVignetteBitmapDisplayer 圆角显示,颜色会有个渐变的效果
SimpleBitmapDisplayer 简单实现
FileNameGenerator
文件名生成HashCodeFileNameGenerator 以imguri的hashcode为name
Md5FileNameGenerator 以imguri的md5值为name
ImageLoadingListener
void onLoadingStarted(String imageUri, View view); 加载开始 void onLoadingFailed(String imageUri, View view, FailReason failReason); 加载失败 void onLoadingComplete(String imageUri, View view, Bitmap loadedImage); 加载完成 void onLoadingCancelled(String imageUri, View view); 取消加载
SimpleImageLoadingListener 一个空实现, 不需要全部实现时,可以使用它。
ImageLoadingProgressListener
void onProgressUpdate(String imageUri, View view, int current, int total);加载进度监听器。current:当前完成大小; total:文件总大小。示例中算进度: 100.0f * current / total,这里的progressBar的max在layout中设置为100。
PauseOnScrollListener
listView.setOnScrollListener(new PauseOnScrollListener(ImageLoader.getInstance(), pauseOnScroll, pauseOnFling));lists-widget滚动时的监听器
注意事项
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();
遇到的Bug:
用UIL加载res/drawable/ 固定资源id的图片,可能会造成图片显示的问题。
因为UIL会根据其id,也就是图片名字,作MD5命名,缓存在sdcard和memory中。
如果早期版本中已经缓存过某一id的图片,而新版本中对这个图片改了图片内容,那么就可能图片显示混乱了。
解决:在加载res/drawable中的图片时,DisplayImageOptions.Builder().cacheInMemory(false); 即不要在sdcard缓存
参考链接: http://blog.csdn.net/vipzjyno1/article/details/23206387
———————————————————————— updated on 2016-12-04 ————————————————————————
UIL作者,维护到1.9.5版后,就声明不再更新维护了。
因工作需要,使用了UIL,进行了一些源码重写,并提供工具类: https://github.com/aa86799/UILRevision
相关文章推荐
- Android-Universal-Image-Loader 图片加载库 详细分析
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)提供Android studio 的DEMO
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- android Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- 从代码分析Android-Universal-Image-Loader的图片加载、显示流程
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- [学习总结]9、Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)