Universal-Image-Loader 图片异步加载并缓存
Android 开发关于图片的管理的程序相对比较麻烦,需要考虑线程,缓存,内存溢出等一系列的问题。经过多方查找终于找到一个不错的开源组件(Universal-Image-Loader),这个组件也是异步加载并缓存的常用组件之一,通过反编译可以在很多应用上都能看到他的身影。
GitHub 上的下载网址是:https://github.com/nostra13/Android-Universal-Image-Loader ,下载最新的库文件,并且导入到项目的 LIB 下便可以使用。
一、介绍
Android-Universal-Image-Loader 是一个开源的 UI 组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。他已经封装好了一些类和方法,我们可以直接拿来使用,而不用花费自己大量的精力去出来线程,缓存,内存溢出等问题。
二:特点
多线程下载图片,图片可以来源于网络,文件系统,项目文件夹 assets 中以及 drawable 中等。
支持随意的配置 ImageLoader,例如线程池,图片下载器,内存缓存策略,硬盘缓存策略,图片显示选项以及其他的一些配置。
支持图片的内存缓存,文件系统缓存或者 SD 卡缓存。
支持图片下载过程的监听。
根据控件(ImageView)的大小对 Bitmap 进行裁剪,减少 Bitmap 占用过多的内存。
较好的控制图片的加载过程,例如暂停图片加载,重新开始加载图片,一般使用在 ListView,GridView 中,滑动过程中暂停加载图片,停止滑动的时候去加载图片。
提供在较慢的网络下对图片进行加载。
流程图:
三、使用方法
1、导入jar文件
2、添加网络权限
<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(); // 开始构建
以上配置依个人需要进行选择配置,配置好之后调用下面方法进行初始化:
ImageLoader.getInstance().init(config); // 全局初始化此配置
注:ImageLoaderConfiguration 配置中的.discCacheFileNameGenerator()
方法是将缓存下来的文件以什么方式命名,里面可以调用的方法有 :
new Md5FileNameGenerator() // 使用 MD5 对 UIL 进行加密命名
new HashCodeFileNameGenerator() // 使用 HASHCODE 对 UIL 进行加密命名
4、使用 ImageLoader 进行图片加载的时候,先要实例化 ImageLoader,调用以下方法进行实例化,在每个布局里面都要实例化后再使用。
protected ImageLoader imageLoader = ImageLoader.getInstance();
5、对需要显示图片的各种格式 DisplayImageOptions 的设置:
DisplayImageOptions options;
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_launcher) // 设置图片在下载期间显示的图片
.showImageForEmptyUri(R.drawable.ic_launcher) // 设置图片 Uri 为空或是错误的时候显示的图片
.showImageOnFail(R.drawable.ic_launcher) // 设置图片加载/解码过程中错误时候显示的图片
.cacheInMemory(true) // 设置下载的图片是否缓存在内存中
.cacheOnDisc(true) // 设置下载的图片是否缓存在 SD 卡中
.considerExifParams(true) // 是否考虑 JPEG 图像 EXIF 参数(旋转,翻转)
.imageScaleType(ImageScaleType.EXACTLY_STRETCHED) // 设置图片以如何的编码方式显示
.bitmapConfig(Bitmap.Config.RGB_565) // 设置图片的解码类型
.decodingOptions(android.graphics.BitmapFactory.Options decodingOptions) // 设置图片的解码配置
//.delayBeforeLoading(int delayInMillis) // int delayInMillis为你设置的下载前的延迟时间
// 设置图片加入缓存前,对 bitmap 进行设置
//.preProcessor(BitmapProcessor preProcessor)
.resetViewBeforeLoading(true) // 设置图片在下载前是否重置,复位
.displayer(new RoundedBitmapDisplayer(20)) // 是否设置为圆角,弧度为多少
.displayer(new FadeInBitmapDisplayer(100)) // 是否图片加载好后渐入的动画时间
.build(); // 构建完成
以上配置依个人需要进行选择配置,不需要的可以不配置。
注:以上配置中的.imageScaleType(ImageScaleType imageScaleType)
是设置图片的缩放方式,缩放类型 mageScaleType 有:
ImageScaleType.EXACTLY // 图像将完全按比例缩小的目标大小
ImageScaleType.EXACTLY_STRETCHED // 图片会缩放到目标大小完全
ImageScaleType.IN_SAMPLE_INT // 图像将被二次采样的整数倍
ImageScaleType.IN_SAMPLE_POWER_OF_2 // 图片将降低2倍,直到下一减少步骤,使图像更小的目标大小
ImageScaleType.NONE // 图片不会调整
.displayer(BitmapDisplayer displayer)
是设置图片的显示方式,显示方式 displayer:
RoundedBitmapDisplayer(int roundPixels) // 设置圆角图片
FakeBitmapDisplayer() // 这个类什么都没做
FadeInBitmapDisplayer(int durationMillis) // 设置图片渐显的时间
SimpleBitmapDisplayer() // 正常显示一张图片
现在开始按照需求使用缓存
1、纯粹为了加载默认配置的一个图片的方法
/**
* @param url 图片的 URL 地址
* @param imageView 承载图片的 IMAGEVIEW 控件
*/
public void displayImage(String url, ImageView imageView) {}
// 具体实现
ImageLoader.getInstance().displayImage(imageUrl, imageView);
2、加载自定义配置的一个图片的方法
/**
* @param url 图片的 URL 地址
* @param imageView 承载图片的 IMAGEVIEW 控件
* @param options DisplayImageOptions 配置文件
*/
public void displayImage(String url, ImageView imageView, DisplayImageOptions options) {}
// 具体实现
ImageLoader.getInstance().displayImage(imageUrl, imageView, options);
3、图片加载时候带加载情况的监听方法
/**
* @param url 图片的 URL 地址
* @param imageView 承载图片的 IMAGEVIEW 控件
* @param options DisplayImageOptions 配置文件
* @param listener 用于监听图片的下载情况。
*/
public void displayImage(String uri, ImageAware imageAware, DisplayImageOptions options,ImageLoadingListener listener) {}
// 具体实现
imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() {
@Override
public void onLoadingStarted() {
// 开始加载的时候执行
}
@Override
public void onLoadingFailed(FailReason failReason) {
// 加载失败的时候执行
}
@Override
public void onLoadingComplete(Bitmap loadedImage) {
// 加载成功的时候执行
}
@Override
public void onLoadingCancelled() {
// 加载取消的时候执行
}
});
4、图片加载时候,带监听又带加载进度条的情况
public void loadImage(String uri, ImageSize targetImageSize, DisplayImageOptions options, ImageLoadingListener listener, ImageLoadingProgressListener progressListener) {}
// 具体实现
imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() {
@Override
public void onLoadingStarted() {
// 开始加载的时候执行
}
@Override
public void onLoadingFailed(FailReason failReason) {
// 加载失败的时候执行
}
@Override
public void onLoadingComplete(Bitmap loadedImage) {
// 加载成功的时候执行
}
@Override
public void onLoadingCancelled() {
// 加载取消的时候执行
}, new ImageLoadingProgressListener() {
@Override
public void onProgressUpdate(String imageUri, View view, int current, int total) {
// 在这里更新 ProgressBar 的进度信息
}
});
四、注意事项
上述提到的 2 个权限必须加入,否则会出错。
ImageLoaderConfiguration 必须配置并且全局化的初始化这个配置
ImageLoader.getInstance().init(config);
否则也会出现错误提示。ImageLoader 是根据 ImageView 的 height,width 确定图片的宽高。
如果经常出现 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();
。
(完)