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

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

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

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

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

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

2. UIL原理:

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

这里写图片描述

3. 配置和使用:

  1. 新建一个类继承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)) //改变缓存策略,可以用弱引用

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值