一、简单说明
Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。这个开源的东西,比我想象的要强的的多,不但实现合理的图片缓存、异步加载,还可以实现线程池的大小,HTTP选项,内存和光盘高速缓存,显示图像等设置。
其默认的缓存目录是mnt/sdcard/Android/data/your project/下,因为没有提供接口,所以想修改只能改其源代码。
1.到https://github.com/nostra13/Android-Universal-Image-Loader把源代码拿下来
2.导入library项目,修改com.nostra13.universalimageloader.utils.StorageUtils这个类,getExternalCacheDir(Context context)这个方法返回的就是缓存图片目录,getCacheDirectory(Context context)是真正返回缓存目录的方法。
代码目录:
universalimageloader的包结构非常清晰。
二、使用步骤
1、初始化
使用该项目前要在Application中初始化:
public class IssAppContext extends Application {
@Override
public void onCreate() {
super.onCreate();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
getApplicationContext()).threadPriority(Thread.NORM_PRIORITY - 2)
.denyCacheImageMultipleSizesInMemory()
.discCacheFileNameGenerator(new Md5FileNameGenerator())
.tasksProcessingOrder(QueueProcessingType.LIFO).writeDebugLogs()
.build();
// Initialize ImageLoader with configuration.
ImageLoader.getInstance().init(config);
}
}
2、获得ImageLoader对象,设置图片加载属性
imageLoader = ImageLoader.getInstance();
options = new DisplayImageOptions.Builder().resetViewBeforeLoading(true).cacheOnDisc(true)
.imageScaleType(ImageScaleType.EXACTLY).bitmapConfig(Bitmap.Config.RGB_565)
.considerExifParams(true).build();
图片加载属性设置详解:
//设置图片在下载期间显示的图片
showStubImage(R.drawable.ic_launcher)
//设置图片Uri为空或是错误的时候显示的图片
showImageForEmptyUri(R.drawable.ic_empty)
//设置图片加载/解码过程中错误时候显示的图片
showImageOnFail(R.drawable.ic_error)
//设置图片在下载前是否重置,复位
resetViewBeforeLoading()
//设置下载的图片是否缓存在内存中
cacheInMemory()
//设置下载的图片是否缓存在SD卡中
cacheOnDisc()
//设置图片的解码类型
bitmapConfig(Bitmap.Config.RGB_565)
//设置图片的解码配置
decodingOptions(android.graphics.BitmapFactory.Options decodingOptions)
//设置图片下载前的延迟
delayBeforeLoading(int delayInMillis)
//设置额外的内容给ImageDownloader
extraForDownloader(Object extra)
//设置图片加入缓存前,对bitmap进行设置
preProcessor(BitmapProcessor preProcessor)
//设置显示前的图片,显示后这个图片一直保留在缓存中
postProcessor(BitmapProcessor postProcessor)
/**
* 设置图片以如何的编码方式显示 imageScaleType(ImageScaleType imageScaleType)
* EXACTLY :图像将完全按比例缩小的目标大小
* EXACTLY_STRETCHED:图片会缩放到目标大小完全 IN_SAMPLE_INT:图像将被二次采样的整数倍
* IN_SAMPLE_POWER_OF_2:图片将降低2倍,直到下一减少步骤,使图像更小的目标大小
* NONE:图片不会调整
*/
imageScaleType( imageScaleType)
/**
* 设置图片的显示方式 默认值-
* DefaultConfigurationFactory.createBitmapDisplayer()
*
* @param displayer
* RoundedBitmapDisplayer(int roundPixels)设置圆角图片
* FakeBitmapDisplayer()这个类什么都没做
* FadeInBitmapDisplayer(int durationMillis)设置图片渐显的时间
* SimpleBitmapDisplayer()正常显示一张图片
*/
displayer(new RoundedBitmapDisplayer(20))
/**
* 你可以设置你自己实现的内存缓存
*/
memoryCache(new LruMemoryCache(2 * 1024 * 1024))
/**
* 为位图最大内存缓存大小(以字节为单位),默认值,可用应用程序内存的1/8
* 注意:如果你使用这个方法,那么LruMemoryCache将被用作内存缓存。
* 您可以使用memoryCache(MemoryCacheAware)方法来设置自己的MemoryCacheAware的实现。
*/
memoryCacheSize(2 * 1024 * 1024)
/**
* 当同一个Uri获取不同大小的图片,缓存到内存时,只缓存一个。默认会缓存多个不同的大小的相同图片
*/
denyCacheImageMultipleSizesInMemory()
/**
* 设置本地图片缓存 也可以设置你自己实现 盘缓存必需实现 DiscCacheAware接口
* 类型(在com.nostra13.universalimageloader.cache.disc.impl包下能找到如下的类):
* FileCountLimitedDiscCache(File cacheDir, int maxFileCount):设置缓存路径和缓存文件的数量,超过数量后,old将被删除
*
* FileCountLimitedDiscCache(File cacheDir,FileNameGenerator fileNameGenerator,int maxFileCount):第二个参数是通过图片的url生成的 唯一文件名。
*
* LimitedAgeDiscCache(File cacheDir, FileNameGenerator fileNameGenerator, long maxAge) :第二个参数同上
*
* LimitedAgeDiscCache(File cacheDir, long maxAge):maxAge为定义的时间,超过时间后,图片将被删除
*
* TotalSizeLimitedDiscCache(File cacheDir, FileNameGenerator fileNameGenerator, int maxCacheSize) :第二个参数同上
*
* TotalSizeLimitedDiscCache(File cacheDir, int maxCacheSize) :定义缓存的大小,如超过了,就会删除old图片。 UnlimitedDiscCache(File cacheDir) :缓存没有限制
*
* UnlimitedDiscCache(File cacheDir, FileNameGenerator fileNameGenerator):第二个参数同上
*/
discCache(new FileCountLimitedDiscCache(new File("/sdcard/cache"), 100))//
/**
* 设置缓存的大小(以字节为单位)默认:本地缓存是不限制大小
* 注意:如果你使用这个方法,那么TotalSizeLimitedDiscCache将被用作磁盘缓存
* 您可以使用discCache(DiscCacheAware)DiscCacheAware引入自己的实现方法
*
* @param maxCacheSize大小
*/
discCacheSize(10*1024*1024)
/**
* 设置图片保存到本地的参数
* @param maxImageWidthForDiscCache 保存的最大宽度
* @param maxImageHeightForDiscCache 保存的最大高度
* @param compressFormat 保存的压缩格式
* @param compressQuality 提示压缩的程度,有0-100.想png这种图片无损耗,就不必设置了
* @param BitmapProcessor 处理位图,可以更改原来的位图,实现必须是线程安全的。
*/
discCacheExtraOptions(100,10,android.graphics.Bitmap.CompressFormat.JPEG,0, null )
/**
* 设置缓存文件的数量
* @param maxFileCount数量
*/
discCacheFileCount(100)
/**
* .taskExecutor(Executor executor) 添加个线程池,进行下载
*
* @param executor
* 线程池
* 如果进行了这个设置,那么threadPoolSize(int),threadPriority(
* int),tasksProcessingOrder(QueueProcessingType)
* 将不会起作用
*/
taskExecutor(Executor executor)
/**
* 设置缓存文件的名字
*
* @param fileNameGenerator
* discCacheFileNameGenerator(FileNameGenerator
* fileNameGenerator) 参数fileNameGenerator:
* HashCodeFileNameGenerator
* ():通过HashCode将url生成文件的唯一名字
* Md5FileNameGenerator():通过Md5将url生产文件的唯一名字
*/
discCacheFileNameGenerator(new Md5FileNameGenerator())
/**
* 设置用于显示图片的线程池大小
* @param threadPoolSize
*/
threadPoolSize(5)//
/**
* 设置线程的优先级
* @param threadPriority
*/
threadPriority(Thread.MIN_PRIORITY + 3)
/**
* tasksProcessingOrder(QueueProcessingType tasksProcessingType)
* 设置图片下载和显示的工作队列排序
*
* @param tasksProcessingType
*/
tasksProcessingOrder(QueueProcessingType.LIFO)
属性还真不少,不过常用的也就那几个,如果有特殊需求就根据相应的属性进行设置。
3、显示图片
来分别看几种显示的方式:
// 将图片显示任务增加到执行池,图片将被显示到ImageView当轮到此ImageView
imageLoader.displayImage(imageUrls[position], imageView, options);
渐变显示
private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();
/**
* 显示图片
* 参数1:图片url
* 参数2:显示图片的控件
* 参数3:显示图片的设置
* 参数4:监听器
*/
imageLoader.displayImage(imageUrls[position], holder.image, options, animateFirstListener);
/**
* 图片加载第一次显示监听器
* @author Administrator
*
*/
private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener {
static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>());
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
if (loadedImage != null) {
ImageView imageView = (ImageView) view;
// 是否第一次显示
boolean firstDisplay = !displayedImages.contains(imageUri);
if (firstDisplay) {
// 图片淡入效果
FadeInBitmapDisplayer.animate(imageView, 500);
displayedImages.add(imageUri);
}
}
}
}
再加一种在html中加载图片的方法
imageLoader.loadImage(img.getImgSrc(), options, new SimpleImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
// TODO Auto-generated method stub
super.onLoadingStarted(imageUri, view);
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
// TODO Auto-generated method stub
super.onLoadingFailed(imageUri, view, failReason);
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
LogUtil.d(TAG, "webview图片onLoadingComplete");
if (AppContext.WEB_DESDROYED) {
return;
}
if (img != null) {
String url = "file:///"
+ DiscCacheUtils.findInCache(img.getImgSrc(),
imageLoader.getDiscCache());
try {
if (webView != null && img != null && img.getImgId() != null
&& !TextUtils.isEmpty(img.getImgId())) {
webView.loadUrl("javascript:bookSotre1.bookSotreReplace('"
+ img.getImgId() + "','" + url + "')");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
到这差不多了,剩下的就是布局和权限,别忘了添加。以后凡是用到图片加载的项目我建议用这个开源工具,会省去很多事,关键可以避免让人头疼的OOM。