您的位置:首页 > 移动开发 > Android开发

android 开源框架Universal-Image-Loader解析

2015-10-23 16:07 513 查看
Android开发中我们会经常遇到图片过多或操作不当造成OOM异常,有时虽然是解决了这个问题但却会影响程序的运行效率,例如:当用户在快速滑动滚动条的过程中,我们程序在仍在艰难的加载服务器端的图片,这样给用户造成了极不好的体验。其实网络上关于图片的异步加载和缓存的讲解很多,但是其实,写一个这方面的程序还是比较麻烦的,要考虑多线程,缓存,内存溢出等很多方面,针对这一光大开发者都会遇到的问题,开源框架ImageLoader便能很好的解决这一问题

1. 功能特性:

多线程异步加载和显示图片(图片来源于网络、sd卡、assets文件夹,drawable文件夹(不能加载9patch),新增加载视频缩略图)。

支持二级缓存,即内存缓存(软引用)及本地缓存。

对加载过程实现监听和事件处理。通过“listener”监视加载的过程,可以暂停加载图片,在经常使用的ListView、GridView中,可以设置滑动时暂停加。载,停止滑动时加载图片(便于节约流量,在一些优化中可以使用)。

高度可定制化(可以根据自己的需求进行各种配置,如:线程池,图片下载器,内存缓存策略等)。

2. UIL原理:

a.UI:请求数据,使用唯一的Key值索引MemoryCache中的Bitmap。
b.内存缓存:缓存搜索,如果能找到Key值对应的Bitmap,则返回数据。否则执行c。
c.硬盘存储:使用唯一Key值对应的文件名,检索SDCard上的文件。如果有对应文件,使用BitmapFactory.decode*方法,解码Bitmap并返回数据,同时将数据写入缓存。如果没有对应文件,执行d。
d.下载图片:启动异步线程,从数据源下载数据(Web)。
e.若下载成功,将数据同时写入硬盘和缓存,并将Bitmap显示在UI中。




3. 配置和使用:

新建一个类继承Application,实现初始化ImageLoader

public class AppContext extends Application {

private static Context mContext;

@Override
public void onCreate() {
super.onCreate();
mContext = this;
initImageLoader();
}

public static Context getAppContext() {
return context;
}

private final static void initImageLoader() {
ImageLoaderConfiguration config = new  ImageLoaderConfiguration.Builder(context)
.defaultDisplayImageOptions(getDefaultDisplayOption())//显示图片的参数,传入自己配置过得DisplayImageOption对象
.memoryCache(new LruMemoryCache(2 * 1024 * 1024)) //缓存策略
.memoryCacheExtraOptions(480, 800) //即保存的每个缓存文件的最大长宽
.threadPoolSize(5) //线程池内线程的数量,默认是3
.threadPriority(Thread.NORM_PRIORITY - 2) //当同一个Uri获取不同大小的图片,缓存到内存时,只缓存一个。默认会缓存多个不同的大小的相同图片
.denyCacheImageMultipleSizesInMemory() //拒绝同一个url缓存多个图片
.diskCacheSize(50 * 1024 * 1024) //设置磁盘缓存大小 50M
.diskCacheFileNameGenerator(new Md5FileNameGenerator()) //将保存的时候的URI名称用MD5 加密
.imageDownloader(new BaseImageDownloader(this, 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超时时间
.tasksProcessingOrder(QueueProcessingType.LIFO)//设置图片下载和显示的工作队列排序

.build();
ImageLoader.getInstance().init(config);
}

private final static DisplayImageOptions getDefaultDisplayOption() {
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.empty_photo)  // 设置图片Uri为空或是错误的时候显示的图片
.showImageOnFail(R.drawable.empty_photo)     //  设置图片加载或解码过程中发生错误显示的图片
.cacheInMemory(true) // 设置下载的图片是否缓存在内存中
.cacheOnDisk(true) // 设置下载的图片是否缓存在SD卡中
.showImageOnLoading(R.drawable.empty_photo)
.build();
return options;
}
}


2.在清单文件AndroidManifest.xml中的application节点中加入

android:name=".MyApplication"


3.在Activity中使用ImageLoader:

ImageLoader.getInstance().displayImage(uri, imageView);


清除缓存的方法有:

ImageLoader.getInstance().clearDiskCache();
ImageLoader.getInstance().clearMemoryCache();


4. Universal-Image-Loader的内存缓存策略:

1.强引用缓存:
LruMemoryCache(这个类就是这个开源框架默认的内存缓存类,缓存的是bitmap的强引用)

好处:滑动时图片不会容易被清除,体验好;坏处:容易出现OOM

2.使用强引用和弱引用相结合的缓存有:
UsingFreqLimitedMemoryCache(如果缓存的图片总量超过限定值,先删除使用频率最小的bitmap)
LRULimitedMemoryCache(这个也是使用的lru算法,和LruMemoryCache不同的是,他缓存的是bitmap的弱引用)
FIFOLimitedMemoryCache(先进先出的缓存策略,当超过设定值,先删除最先加入缓存的bitmap)
LargestLimitedMemoryCache(当超过缓存限定值,先删除最大的bitmap对象)
LimitedAgeMemoryCache(当 bitmap加入缓存中的时间超过我们设定的值,将其删除)

3.只使用弱引用缓存:
WeakMemoryCache(这个类缓存bitmap的总大小没有限制,唯一不足的地方就是不稳定,缓存的图片容易被回收掉)

好处:对缓存的bitmap总大小无限制;坏处:使得图片不稳定,图片极其容易被回收

*注意:不要使用.cacheInMemory();*


5. Universal-Image-Loader的硬盘缓存策略

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)) //改变缓存策略,可以用弱引用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: