最近在学习Universal-Image-Loader源码(https://github.com/nostra13/Android-Universal-Image-Loader)。它是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。
支持多线程图片加载
提供丰富的细节配置,比如线程池大小,HTPP请求项,内存和磁盘缓存,图片显示时的参数配置等等;
提供双缓存
支持加载过程的监听;
提供图片的个性化显示配置接口;
通过看源码我找到了如下一些类的对应关系,这样可以在进行一些configure设置的时候有多的选择
获取实例。ImageLoader采用单例模式
imageLoader = ImageLoader.getInstance();
ImageLoaderConfiguration的生成
方法一。默认设置
ImageLoaderConfiguration config = ImageLoaderConfiguration.createDefault(context);
方法二。自定义设置
ImageLoaderConfiguration config = null;
try {
config = new ImageLoaderConfiguration.Builder(context)
// 保存的每个缓存文件的最大长宽
.memoryCacheExtraOptions(480, 800)
// 在图片被保存到sd卡之前设置压缩选项
// 最后一个参数通常直接设置为null
.diskCacheExtraOptions(480, 800, new BitmapProcessor() {
@Override
public Bitmap process(Bitmap bitmap) {
return null;
}
})
// 为下载和显示图片设置Executor。通常为null,否则一些设置项就无效了
.taskExecutor(new Executor() {
@Override
public void execute(Runnable command) {
}
})
// 为Cache中的图片设置Executor。通常为null,否则一些设置项就无效了
.taskExecutorForCachedImages(new Executor() {
@Override
public void execute(Runnable command) {
}
})
// 线程池内加载的数量
.threadPoolSize(3)
// 线程优先级
.threadPriority(Thread.NORM_PRIORITY - 2)
// deny cache multiple sizes of one image in memory
.denyCacheImageMultipleSizesInMemory()
// 下载和显示图片的顺序(二选一,先进先出,后进先出)
.tasksProcessingOrder(QueueProcessingType.FIFO)
.tasksProcessingOrder(QueueProcessingType.LIFO)
// maximum memory cache size--2M
.memoryCacheSize(2 * 1024 * 1024)
// maximum memory cache size(百分比)13是默认值
.memoryCacheSizePercentage(13)
// memoryCache类型(八选一,这四个常用)
// 余下四个在cache.memory.impl包里面有
.memoryCache(
new UsingFreqLimitedMemoryCache(2 * 1024 * 1024))
.memoryCache(new LRULimitedMemoryCache(2 * 1024 * 1024))
.memoryCache(new FIFOLimitedMemoryCache(2 * 1024 * 1024))
.memoryCache(new LargestLimitedMemoryCache(2 * 1024 * 1024))
// disk cache类型(四选一)
.diskCache(new UnlimitedDiskCache(context.getCacheDir()))
.diskCache(
new LimitedAgeDiskCache(context.getCacheDir(),
50 * 1024 * 1024))
.diskCache(
new LruDiskCache(context.getCacheDir(),
new Md5FileNameGenerator(),
50 * 1024 * 1024))
.diskCache(
new LruDiskCache(context.getCacheDir(),
new HashCodeFileNameGenerator(),
50 * 1024 * 1024))
.diskCacheSize(50 * 1024 * 1024)
.diskCacheFileCount(100)
// 用什么方式来命名缓存文件名(二选一)
.diskCacheFileNameGenerator(new Md5FileNameGenerator())
.diskCacheFileNameGenerator(new HashCodeFileNameGenerator())
// 指定谁来下载Image
.imageDownloader(new BaseImageDownloader(context))
// 谁来decode image stream
.imageDecoder(new BaseImageDecoder(true))
// 这个选项可以不设置,后面也有机会设置
.defaultDisplayImageOptions(
DisplayImageOptions.createSimple())
.writeDebugLogs().build();
} catch (IOException e) {
e.printStackTrace();
}
加载ImageLoaderConfiguration
imageLoader.init(config);
展示图片
图片url就用一张美女图片吧
String uri = "http://hbimg.b0.upaiyun.com/4282ac737c858ea9c325bbf11bc6539a754738341be76-LqInUK_fw658";
当然还可以从其他地方加载
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)
展示图片方法一
功能:将uri中的图片放到imageView控件中
imageLoader.displayImage(uri, imageView);
这里的imageView就是xml文件中的控件
展示图片方法二
和方法一类似
imageLoader.displayImage(uri, new ImageViewAware(imageView));
展示图片方法三
带监听器
imageLoader.displayImage(uri, new ImageViewAware(imageView),
new ImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
}
@Override
public void onLoadingFailed(String imageUri, View view,
FailReason failReason) {
}
@Override
public void onLoadingComplete(String imageUri, View view,
Bitmap loadedImage) {
}
@Override
public void onLoadingCancelled(String imageUri, View view) {
}
});
展示图片方法四
带DisplayImageOptions
imageLoader.displayImage(uri, new ImageViewAware(imageView), options);
那么DisplayImageOptions的生成方法可以是默认的
DisplayImageOptions options = DisplayImageOptions.createSimple();
也可以是自定义的
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_launcher)
.showImageForEmptyUri(R.drawable.ic_launcher)
.showImageOnFail(R.drawable.ic_launcher)
.resetViewBeforeLoading(true)
.cacheInMemory(true)
.cacheOnDisk(true)
.imageScaleType(ImageScaleType.NONE)
.bitmapConfig(Config.ARGB_8888)
// Options里面有默认的值
.decodingOptions(new Options())
.delayBeforeLoading(1000)
// 是否考虑JPEG图像EXIF参数(旋转,翻转)
.considerExifParams(true)
// before they will be cached in memory
.preProcessor(new BitmapProcessor() {
@Override
public Bitmap process(Bitmap bitmap) {
return null;
}
})
// before they will be displayed in ImageAware
.postProcessor(new BitmapProcessor() {
@Override
public Bitmap process(Bitmap bitmap) {
return null;
}
})
// 以什么样的形式展示Image(五选一)
.displayer(new SimpleBitmapDisplayer())
.displayer(new CircleBitmapDisplayer())
.displayer(new FadeInBitmapDisplayer(1000))
.displayer(new RoundedBitmapDisplayer(45))
.displayer(new RoundedVignetteBitmapDisplayer(45, 0)).build();
当然,不能忘了权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
还要注意
如果经常出现OOM(别人那边看到的,觉得很有提的必要)
①减少配置之中线程池的大小,(.threadPoolSize).推荐1-5;
②使用.bitmapConfig(Bitmap.config.RGB_565)代替ARGB_8888;
③使用.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者.imageScaleType(ImageScaleType.EXACTLY);
④避免使用RoundedBitmapDisplayer.他会创建新的ARGB_8888格式的Bitmap对象;
参考文献:http://blog.csdn.net/shimiso/article/details/40889499
http://my.oschina.net/lhjtianji/blog/508518