Android-Universal-Image-Loader是一个开源的图片框架程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。所以,如果你的程序里需要这个功能的话,那么不妨试试它。因为已经封装好了一些类和方法。我们 可以直接拿来用了。而不用重复去写了。
Android-Universal-Image-Loader下载地址:https://github.com/nostra13/Android-Universal-Image-Loader
我们可以先看看这个开源库存在哪些特征
- 多线程下载图片,图片可以来源于网络,文件系统,项目文件夹assets中以及drawable中等
- 支持随意的配置ImageLoader,例如线程池,图片下载器,内存缓存策略,硬盘缓存策略,图片显示选项以及其他的一些配置
- 支持图片的内存缓存,文件系统缓存或者SD卡缓存
- 支持图片下载过程的监听
- 根据控件(ImageView)的大小对Bitmap进行裁剪,减少Bitmap占用过多的内存
- 较好的控制图片的加载过程,例如暂停图片加载,重新开始加载图片,一般使用在ListView,GridView中,滑动过程中暂停加载图片,停止滑动的时候去加载图片
- 提供在较慢的网络下对图片进行加载
首先我们需要自定义Application文件,在Application中完成ImageLoader的配置。
然后我们需要添加ImageLoader需要的权限:
<uses-permission android:name="android.permission.INTERNET" />
<!-- Include next permission if you want to allow UIL to cache images on SD card -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
好了,现在我们可以去配置ImageLoader信息了。第一步就是完成ImageLoaderConfiguration的配置
//配置imagerloader的参数
ImageLoaderConfiguration config =new ImageLoaderConfiguration.Builder(getApplicationContext())
.threadPoolSize(5)//设置线程数量一般1-5最好
.denyCacheImageMultipleSizesInMemory()
.threadPriority(Thread.MAX_PRIORITY-2)//线程的优先级
.tasksProcessingOrder(QueueProcessingType.FIFO) // default
.memoryCacheExtraOptions(480, 800)//缓存的最大宽高
.discCacheExtraOptions(480, 800,CompressFormat.JPEG, 80)//本地存储的图片最大宽高和质量
.memoryCache(new UsingFreqLimitedMemoryCache(2*1024*1024))//自定义内存缓存,如果出现内存溢出可以不添加
.memoryCacheSize(2*1024*1024)//最大的缓存数量
.discCache(new UnlimitedDiscCache(cachefile)) // default 可以自定义缓存路径
.discCacheSize(50 * 1024 * 1024) // 50 Mb sd卡(本地)缓存的最大值
// .diskCacheFileCount(100) // 可以缓存的文件数量
.discCacheFileNameGenerator(new Md5FileNameGenerator())//加密
.imageDownloader(new BaseImageDownloader(getApplicationContext(), 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)//定义超时
.defaultDisplayImageOptions(dconfig)//
.enableLogging()//输出日志
.build();
对于更新之后的配置信息其实也没有什么大的差别就是一些方法的弃用:
ImageLoaderConfiguration config =new ImageLoaderConfiguration.Builder(getApplicationContext())
.threadPoolSize(5)//设置线程数量一般1-5最好
.denyCacheImageMultipleSizesInMemory()
.threadPriority(Thread.MAX_PRIORITY-2)//线程的优先级
.tasksProcessingOrder(QueueProcessingType.FIFO) // default
.memoryCacheExtraOptions(480, 800)//缓存的最大宽高
.diskCacheExtraOptions(480, 800,null)//本地存储的最大宽高
.memoryCache(new UsingFreqLimitedMemoryCache(2*1024*1024))//自定义内存缓存,如果出现内存溢出可以不添加
.memoryCacheSize(2*1024*1024)//最大的缓存数量
.diskCache(new UnlimitedDiskCache(cacheDir)) // default 可以自定义缓存路径
.diskCacheSize(50 * 1024 * 1024) // 50 Mb sd卡(本地)缓存的最大值
// .diskCacheFileCount(100) // 可以缓存的文件数量
.diskCacheFileNameGenerator(new Md5FileNameGenerator())//加密
.imageDownloader(new BaseImageDownloader(getApplicationContext(), 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)
.defaultDisplayImageOptions(dconfig)//
.writeDebugLogs()//输出日志
.build();
再来就是对DisplayImageOptions的配置了
DisplayImageOptions dconfig = null;
dconfig = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.ic_empty)//图片加载过程中显示的默认图片
.showImageOnFail(R.drawable.ic_error)//加载图片出错显示的图片
.cacheInMemory(true)//是否加载缓存
.cacheOnDisk(true)//是否存储本地
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.EXACTLY)
//.displayer(new FadeInBitmapDisplayer(100))//设置图片渐显的时间
//.FadeInBitmapDisplayer()//设置图片渐显的时间
// .SimpleBitmapDisplayer()//正常显示一张图片
//.displayer(new SimpleBitmapDisplayer())//设置正常显示一张图片
.build();
最后一步就是要在Application的OnCreat方法中添加:
ImageLoader.getInstance().init(config);
到这imageLoader的配置就基本完成了。
最后不要忘记在AndroidManifest.xml配置Application的信息
配置完成了,快让我们一起感受一下它的强大:
1)方法1:最简单的方式,我们只需要定义要显示的图片的URL和要显示图片的ImageView。这种情况下,图片的显示选项会使用默认的配置
2)方法2:加载自定义配置的一个图片
3)方法3:加载带监听的一个图片
4)方法4:加载自定义配置且带监听的一个图片
ImageLoader.getInstance().displayImage(url,imageView);
ImageLoader.getInstance().displayImage(uri, imageView, options);
ImageLoader.getInstance().displayImage(uri, imageView, new ImageLoadingListener() {
@Override
public void onLoadingStarted(String arg0, View arg1) {
// TODO Auto-generated method stub
}
@Override
public void onLoadingFailed(String arg0, View arg1, FailReason arg2) {
// TODO Auto-generated method stub
}
@Override
public void onLoadingComplete(String arg0, View arg1, Bitmap arg2) {
// TODO Auto-generated method stub
}
@Override
public void onLoadingCancelled(String arg0, View arg1) {
// TODO Auto-generated method stub
}
});
ImageLoader.getInstance().displayImage(url[position], holder.imageView, options, new ImageLoadingListener() {
@Override
public void onLoadingStarted(String arg0, View arg1) {
// TODO Auto-generated method stub
}
@Override
public void onLoadingFailed(String arg0, View arg1, FailReason arg2) {
// TODO Auto-generated method stub
}
@Override
public void onLoadingComplete(String arg0, View arg1, Bitmap arg2) {
// TODO Auto-generated method stub
}
@Override
public void onLoadingCancelled(String arg0, View arg1) {
// TODO Auto-generated method stub
}
});
备注:
1).imageScaleType(ImageScaleType imageScaleType) //设置图片的缩放方式
缩放类型mageScaleType:
EXACTLY :图像将完全按比例缩小的目标大小
EXACTLY_STRETCHED:图片会缩放到目标大小完全
IN_SAMPLE_INT:图像将被二次采样的整数倍
IN_SAMPLE_POWER_OF_2:图片将降低2倍,直到下一减少步骤,使图像更小的目标大小
NONE:图片不会调整
2).displayer(BitmapDisplayer displayer) //设置图片的显示方式
显示方式displayer:
RoundedBitmapDisplayer(int roundPixels)设置圆角图片
FakeBitmapDisplayer()这个类什么都没做
FadeInBitmapDisplayer(int durationMillis)设置图片渐显的时间
SimpleBitmapDisplayer()正常显示一张图片
参数补充:
.considerExifParams(true) //是否考虑JPEG图像EXIF参数(旋转,翻转)
.displayer(new FadeInBitmapDisplayer(100))// 图片加载好后渐入的动画时间
开启缓存后默认会缓存到外置SD卡如下地址(/sdcard/Android/data/[package_name]/cache).
.imageDownloader(new BaseImageDownloader(context, 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超时时间
FileCountLimitedDiscCache(可以设定缓存图片的个数,当超过设定值,删除掉最先加入到硬盘的文件)
LimitedAgeDiscCache(设定文件存活的最长时间,当超过这个值,就删除该文件)
TotalSizeLimitedDiscCache(设定缓存bitmap的最大值,当超过这个值,删除最先加入到硬盘的文件)
UnlimitedDiscCache(这个缓存类没有任何的限制)
虽然这个框架有很好的缓存机制,有效的避免了OOM的产生,一般的情况下产生OOM的概率比较小,但是并不能保证OutOfMemoryError永远不发生,这个框架对于OutOfMemoryError做了简单的catch,保证我们的程序遇到OOM而不被crash掉,但是如果我们使用该框架经常发生OOM,我们应该怎么去改善呢?
- 减少线程池中线程的个数,在ImageLoaderConfiguration中的(.threadPoolSize)中配置,推荐配置1-5
- 在DisplayImageOptions选项中配置bitmapConfig为Bitmap.Config.RGB_565,因为默认是ARGB_8888, 使用RGB_565会比使用ARGB_8888少消耗2倍的内存
- 在ImageLoaderConfiguration中配置图片的内存缓存为memoryCache(new WeakMemoryCache()) 或者不使用内存缓存
- 在DisplayImageOptions选项中设置.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者imageScaleType(ImageScaleType.EXACTLY)