Universal-Image-Loader解析(一)——ImageLoaderConfiguration的详细配置
本篇文章主要介绍了"Universal-Image-Loader解析(一)——ImageLoaderConfiguration的详细配置 ",主要涉及到Universal-Image-Loader解析(一)——ImageLoaderConfiguration的详细配置 方面的内容,对于Universal-Image-Loader解析(一)——ImageLoaderConfiguration的详细配置 感兴趣的同学可以参考一下。
Universal-Image-Loader这个开源框架又来给我们造福了,它是一个图片加载框架,主要强大在于可以用于网络等图片源的加载,并且有多重缓存机制。先给出其项目地址:https://github.com/nostra13/Android-Universal-Image-Loader
一、简要说明:
1.多线程下载图片,图片可以来源于网络,文件系统,项目文件夹assets中以及drawable中等
2.支持随意的配置ImageLoader,例如线程池,图片下载器,内存缓存策略,硬盘缓存策略,图片显示选项以及其他的一些配置
3.支持图片的内存缓存,文件系统缓存或者SD卡缓存
4.支持图片下载过程的监听
5.根据控件(ImageView)的大小对Bitmap进行裁剪,减少Bitmap占用过多的内存
6.较好的控制图片的加载过程,例如暂停图片加载,重新开始加载图片,一般使用在ListView,GridView中,滑动过程中暂停加载图片,停止滑动的时候去加载图片
7.提供在较慢的网络下对图片进行加载
二、配置和使用
1.新建一个类继承Application,实现初始化ImageLoader
ImageLoader是一个配置方案,主要是一次性的配置项目中的缓存策略,这样独立的配置很便于模块化。
@Override public void onCreate() { // TODO 自动生成的方法存根 super.onCreate(); //通过配置方案来初始化ImageLoader ImageLoader.getInstance().init(ImageLoaderConfiguration configuration);
}
这里的参数是一个ImageLoaderConfiguration,这个对象可以设置缓存,缓存路径等等,下面我们先得到一个默认的配置好的对象。
它使用了Build模式,这样我们就可以很方便的来得到一个默认的配置好的ImageLoaderConfiguration对象
/** * 创建默认的ImageLoader配置参数,这里创建了一个默认的配置方案 * @return */ private ImageLoaderConfiguration getDefaultConfig() { ImageLoaderConfiguration config = ImageLoaderConfiguration.createDefault(getApplicationContext()); return config; }
当然,ImageLoaderConfiguration有多重选项可以配置。下面是各种属性和自己的默认值
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context) .memoryCacheExtraOptions(480, 800) // default = device screen dimensions .diskCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null) .taskExecutor(...) .taskExecutorForCachedImages(...) .threadPoolSize(3) // default .threadPriority(Thread.NORM_PRIORITY - 1) // default .tasksProcessingOrder(QueueProcessingType.FIFO) // default .denyCacheImageMultipleSizesInMemory() .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) .memoryCacheSize(2 * 1024 * 1024) .memoryCacheSizePercentage(13) // default .diskCache(new UnlimitedDiscCache(cacheDir)) // default .diskCacheSize(50 * 1024 * 1024) .diskCacheFileCount(100) .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default .imageDownloader(new BaseImageDownloader(context)) // default .imageDecoder(new BaseImageDecoder()) // default .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default .writeDebugLogs() .build();
example:
/** * 所有的配置参数举例 * @return */ private ImageLoaderConfiguration getWholeConfig() { //设置默认的配置,设置缓存,这里不设置可以到别的地方设置 DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder() .cacheInMemory(true) .cacheOnDisk(true) .build(); //设置缓存的路径 File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache"); ImageLoaderConfiguration config = new ImageLoaderConfiguration .Builder(getApplicationContext()) .memoryCacheExtraOptions(480, 800) //即保存的每个缓存文件的最大长宽 .threadPoolSize(3) //线程池内加载的数量 .threadPriority(Thread.NORM_PRIORITY - 2) //解释:当同一个Uri获取不同大小的图片,缓存到内存时,只缓存一个。默认会缓存多个不同的大小的相同图片 .denyCacheImageMultipleSizesInMemory() //拒绝缓存多个图片。 .memoryCache(new WeakMemoryCache()) //缓存策略你可以通过自己的内存缓存实现 ,这里用弱引用,缺点是太容易被回收了,不是很好! .memoryCacheSize(2 * 1024 * 1024) //设置内存缓存的大小 .diskCacheSize(50 * 1024 * 1024) //设置磁盘缓存大小 50M .diskCacheFileNameGenerator(new Md5FileNameGenerator()) //将保存的时候的URI名称用MD5 加密 .tasksProcessingOrder(QueueProcessingType.LIFO) //设置图片下载和显示的工作队列排序 .diskCacheFileCount(100) //缓存的文件数量 .diskCache(new UnlimitedDiskCache(cacheDir)) //自定义缓存路径 .defaultDisplayImageOptions(defaultOptions) //显示图片的参数,默认:DisplayImageOptions.createSimple() .imageDownloader(new BaseImageDownloader(this, 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超时时间 .writeDebugLogs() //打开调试日志 .build();//开始构建
return config; }
刚开始别被吓跑了,其实看起来多,我们一般只需要知道这是做什么的,然后根据自己的需求配置即可。
常用配置:
/** * 比较常用的配置方案 * @return */ private ImageLoaderConfiguration getSimpleConfig() { //设置缓存的路径 File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache"); ImageLoaderConfiguration config = new ImageLoaderConfiguration .Builder(getApplicationContext()) .memoryCacheExtraOptions(480, 800) //即保存的每个缓存文件的最大长宽 .threadPriority(Thread.NORM_PRIORITY - 2) //线程池中线程的个数 .denyCacheImageMultipleSizesInMemory() //禁止缓存多张图片 .memoryCache(new LRULimitedMemoryCache(40*1024*1024)) //缓存策略 .memoryCacheSize(50 * 1024 * 1024) //设置内存缓存的大小 .diskCacheFileNameGenerator(new Md5FileNameGenerator()) //缓存文件名的保存方式 .diskCacheSize(200 * 1024 * 1024) //磁盘缓存大小 .tasksProcessingOrder(QueueProcessingType.LIFO) //工作队列 .diskCacheFileCount(200) //缓存的文件数量 .diskCache(new UnlimitedDiskCache(cacheDir)) //自定义缓存路径 //.writeDebugLogs() // Remove for release app .build(); return config; }
注:这里面有多个参数是有待商榷的,自己根据需求配置即可!
在Activity中清除缓存的方法:
//清除缓存 ImageLoader.getInstance().clearDiskCache(); ImageLoader.getInstance().clearMemoryCache();
Manifest.xml 中加入权限,并且配置Application!
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.kale.universalimageloadertest" android:versionCode="1" android:versionName="1.0" > <!-- 访问internet的权限 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- Include next permission if you want to allow UIL to cache images on SD card --> <!-- 写入sd卡的权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <!-- 添加进自己的Application --> <application android:name="com.kale.universalimageloadertest.application.MyApplication" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.kale.universalimageloadertest.UILListActivity"/> </application> </manifest>
MyApplication.JAVA
package com.kale.universalimageloadertest.application; import java.io.File; import android.app.Application; import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache; import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator; import com.nostra13.universalimageloader.cache.memory.impl.FIFOLimitedMemoryCache; import com.nostra13.universalimageloader.cache.memory.impl.LRULimitedMemoryCache; import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.core.assist.QueueProcessingType; import com.nostra13.universalimageloader.core.download.BaseImageDownloader; import com.nostra13.universalimageloader.utils.StorageUtils; /** * @author:Jack Tony * @tips :新建一个MyApplication继承Application,并在onCreate() * 中创建ImageLoader的配置参数,并初始化到ImageLoader中代码 * @date :2014-10-15 */ public class MyApplication extends Application{ @Override public void onCreate() { // TODO 自动生成的方法存根 super.onCreate(); //通过配置方案来初始化ImageLoader ImageLoader.getInstance().init(getSimpleConfig()); } /** * 创建默认的ImageLoader配置参数,这里创建了一个默认的配置方案 * @return */ private ImageLoaderConfiguration getDefaultConfig() { ImageLoaderConfiguration config = ImageLoaderConfiguration .createDefault(getApplicationContext()); return config; } /** * 所有的配置参数举例 * @return */ private ImageLoaderConfiguration getWholeConfig() { //设置默认的配置,设置缓存,这里不设置可以到别的地方设置 DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder() .cacheInMemory(true) .cacheOnDisk(true) .build(); //设置缓存的路径 File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache"); ImageLoaderConfiguration config = new ImageLoaderConfiguration .Builder(getApplicationContext()) .memoryCacheExtraOptions(480, 800) //即保存的每个缓存文件的最大长宽 .threadPoolSize(3) //线程池内加载的数量 .threadPriority(Thread.NORM_PRIORITY - 2) //解释:当同一个Uri获取不同大小的图片,缓存到内存时,只缓存一个。默认会缓存多个不同的大小的相同图片 .denyCacheImageMultipleSizesInMemory() //拒绝缓存多个图片。 .memoryCache(new WeakMemoryCache()) //缓存策略你可以通过自己的内存缓存实现 ,这里用弱引用,缺点是太容易被回收了,不是很好! .memoryCacheSize(2 * 1024 * 1024) //设置内存缓存的大小 .diskCacheSize(50 * 1024 * 1024) //设置磁盘缓存大小 50M .diskCacheFileNameGenerator(new Md5FileNameGenerator()) //将保存的时候的URI名称用MD5 加密 .tasksProcessingOrder(QueueProcessingType.LIFO) //设置图片下载和显示的工作队列排序 .diskCacheFileCount(100) //缓存的文件数量 .diskCache(new UnlimitedDiskCache(cacheDir)) //自定义缓存路径 .defaultDisplayImageOptions(defaultOptions) //显示图片的参数,默认:DisplayImageOptions.createSimple() .imageDownloader(new BaseImageDownloader(getApplicationContext(), 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超时时间 .writeDebugLogs() //打开调试日志 .build();//开始构建 return config; } /** * 比较常用的配置方案 * @return */ private ImageLoaderConfiguration getSimpleConfig() { //设置缓存的路径 File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache"); ImageLoaderConfiguration config = new ImageLoaderConfiguration .Builder(getApplicationContext()) .memoryCacheExtraOptions(480, 800) //即保存的每个缓存文件的最大长宽 .threadPriority(Thread.NORM_PRIORITY - 2) //线程池中线程的个数 .denyCacheImageMultipleSizesInMemory() //禁止缓存多张图片 .memoryCache(new LRULimitedMemoryCache(50 * 1024 * 1024)) //缓存策略 .memoryCacheSize(50 * 1024 * 1024) //设置内存缓存的大小 .diskCacheFileNameGenerator(new Md5FileNameGenerator()) //缓存文件名的保存方式 .diskCacheSize(200 * 1024 * 1024) //磁盘缓存大小 .tasksProcessingOrder(QueueProcessingType.LIFO) //工作队列 .diskCacheFileCount(200) //缓存的文件数量 .diskCache(new UnlimitedDiskCache(cacheDir)) //自定义缓存路径 //.writeDebugLogs() // Remove for release app .build(); return config; } /* ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context) .memoryCacheExtraOptions(480, 800) // default = device screen dimensions .diskCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null) .taskExecutor(...) .taskExecutorForCachedImages(...) .threadPoolSize(3) // default .threadPriority(Thread.NORM_PRIORITY - 1) // default .tasksProcessingOrder(QueueProcessingType.FIFO) // default .denyCacheImageMultipleSizesInMemory() .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) .memoryCacheSize(2 * 1024 * 1024) .memoryCacheSizePercentage(13) // default .diskCache(new UnlimitedDiscCache(cacheDir)) // default .diskCacheSize(50 * 1024 * 1024) .diskCacheFileCount(100) .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default .imageDownloader(new BaseImageDownloader(context)) // default .imageDecoder(new BaseImageDecoder()) // default .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default .writeDebugLogs() .build(); */ }
Universal-Image-Loader的内存缓存策略
详细的缓存策略可以移步:http://blog.csdn.net/xiaanming/article/details/27525741,下方是总结的结果:
1.强引用缓存
LruMemoryCache(这个类就是这个开源框架默认的内存缓存类,缓存的是bitmap的强引用)
好处:滑动时图片不会容易被清除,体验好;坏处:容易出现OOM
2.使用强引用和弱引用相结合的缓存有
UsingFreqLimitedMemoryCache(如果缓存的图片总量超过限定值,先删除使用频率最小的bitmap)
LRULimitedMemoryCache(这个也是使用的lru算法,和LruMemoryCache不同的是,他缓存的是bitmap的弱引用)
FIFOLimitedMemoryCache(先进先出的缓存策略,当超过设定值,先删除最先加入缓存的bitmap)
LargestLimitedMemoryCache(当超过缓存限定值,先删除最大的bitmap对象)
LimitedAgeMemoryCache(当 bitmap加入缓存中的时间超过我们设定的值,将其删除)
3.只使用弱引用缓存
WeakMemoryCache(这个类缓存bitmap的总大小没有限制,唯一不足的地方就是不稳定,缓存的图片容易被回收掉)
好处:对缓存的bitmap总大小无限制;坏处:使得图片不稳定,图片极其容易被回收
注意:不要使用.cacheInMemory();
Universal-Image-Loader的硬盘缓存策略
详细的硬盘缓存策略可以移步:http://blog.csdn.net/xiaanming/article/details/27525741,下方是总结的结果:
FileCountLimitedDiscCache(可以设定缓存图片的个数,当超过设定值,删除掉最先加入到硬盘的文件)
LimitedAgeDiscCache(设定文件存活的最长时间,当超过这个值,就删除该文件)
TotalSizeLimitedDiscCache(设定缓存bitmap的最大值,当超过这个值,删除最先加入到硬盘的文件)
UnlimitedDiscCache(这个缓存类没有任何的限制)
在ImageLoaderConfiguration中配置了diskCacheSize和diskCacheFileCount,他就使用的是LruDiscCache,否则使用的是UnlimitedDiscCache
在最新的源码中还有一个硬盘缓存类可以配置,那就是LimitedAgeDiscCache,可以在ImageLoaderConfiguration.diskCache(...)配置
避免OOM
为了避免OOM,可以修改下面的配置方案:
.memoryCacheExtraOptions(480, 800) //即保存的每个缓存文件的最大长宽,大小自行配制
.threadPriority(Thread.NORM_PRIORITY - 2) //线程池中线程的个数,一般配置1-5,这里配的是3
.memoryCache(new LRULimitedMemoryCache(40*1024*1024)) //改变缓存策略,可以用弱引用
参考自:
http://blog.csdn.net/xiaanming/article/details/26810303
http://blog.csdn.net/xiaanming/article/details/27525741
http://blog.csdn.net/vipzjyno1/article/details/23206387