微信号:androidwalker

介绍:关注Android新技术、进阶开发

开源组件:Universal Image Loader

2016-06-20 07:41 xjj_app


在线加载图片,在Android开发里,可是一个头疼的问题。因为没有现成的库来提供支持,唯有开发者自己开发一套图片加载库,或者使用现成的库。这就是我们今天想推荐一套非常适合入门使用的开源库——Universal Image Loader。


1 需求


        我们在做开发时,列表显示图片的设计少不了。如下所示:


       产品要求我们从服务器拉取到列表信息(里面包含图片地址), 再分别请求这些图片地址, 显示在列表中。



2 方案V1.0


       2012年,刚开始看这个需求,我就乐了。这不就是简单将图片下载下来,然后再显示出来嘛。于是我的设计如下:


        设计的思路如下:

  • 本地存储(Sdcard/data缓存),节省流量,便达到下次使用可以快速展示的目的;

  • 下载管理器,实现传入url后,就可以去服务器下载图片资源;

  • 下载的图片资源,先cache到内存,再进行展示,同时保存到sdcard/data里,以便再次使用。

        

       基于上述思路,我很快实现了该方案。用起来后,发现还是管用的,但是有一个问题,加载项多了之后,就很容易出现OOM。



3 方案V1.1


       意识到使用起来很容易出现OOM,尤其是项比较多或是图片比较大的情况。所以,我想到了对上述方案进行一番的优化。我仔细审阅了自己的方案,感觉自己还是too young, too simple。发现存在以下问题:

  • 强引用问题。存储在内存的Drawable都是采用强引用的方式,导致图片资源无法释放,越积越多。

  • 图片尺寸太大问题。由于下发的图片比较大,部分图片远远超出了实际需要的大小。


        找到问题的根本所在之后,这下就可以对症下药。基于V1.0方案,设计出了V1.1 修正版方案。


        修正版方案,引入了两个新特性:

1)Drawable资源全部改为WeakReference时,这样可以避免不使用的Drawable无法被系统gc问题。

2)同时,针对大图片问题,则增加一层检测机制,如果图片过大,则进行压缩处理,从而确保不使用过大的图片。


       有了V1.1 方案后,列表可以加载的项更多了,比较难出现OOM,基本满足了我们项目的要求。



4 方案V1.2


       有了方案V1.1之后,正常工作基本没问题,但在使用体验上却有一些细节点可以继续优化:

  • 快速滑动,不断地下载图片和显示图片,对性能影响很大,而且容易带来一些额外的流量消耗。

  • 图片内存缓存策略单一。只是简单使用List或Map缓存,没有一种很好地机制来规划内存的回收。




        基于上述提到的问题:

1)我采用Android提供的LruCache,可以设置阀值,一旦超出该阀值,则会自动回收最近很少被使用到的资源。属于比较好的无效资源淘汰算法。

2)同时,在滑动listview时,不去执行操作,只有listview滑动结束后,才去加载图片。



5 方案V2.0


        虽然,自己设计的方案从整体上达到项目的要求,但是有一天,我发现我自己设计这套思路,在github已经有线程的开源方案,这时候才意识到自己重复造轮子的必要性太低了。毕竟有这么多人在follow做这个事情,自己做的功能和它比起来简直是小巫见大巫了~


        从上面的注释可以看出,这是一个功能强大、灵活性很高的图片加载库,可以用在Android上下载、缓存和显示图片。它具有以下特性

  • 多线程加载图片(异步、同步)

  • 丰富的图片加载配置(线程执行器、下载器、图片压缩、内存/磁盘缓存显示图片等配置),自己可以根据需要设置参数。

  • 图片可以缓存到内存或是磁盘(sdcard或data)

  • 监听加载进度

  • 支持Android 2.0+

      

        基本使用示例如下:

    

        从上面可以看到,ImageLoader 采用单例方式,通过调用displayImage来显示,传入参数为图片的url和ImageView视图。

        loadImage 也是加载图片,同时可以设置监听,在加载图片完成后,可以对加载到的loadedImage做进一步的处理。

        以下是Universal Image Loader 的工作流程图,分为三种情况:

1)Bitmap已经在内存中

2)Bitmap已经在磁盘中

3)没有缓存的Bitmap

        基本上,和我之前的方案相差不大,但做了更多的细化优化。





6 传送门



        篇幅的关系,我们这边就不再一一来讲解,universal image loader的接入很简单,感兴趣的童鞋可以在这里下载到相应的源码:https://github.com/nostra13/Android-Universal-Image-Loader



 
Android高级开发 更多文章 Android Studio 入门技巧之<基础篇> Android Studio 之<进阶篇:实用快捷键> Android Studio 之<进阶篇:IDE设置> 2015年度腾讯MIG内部技术峰会 多团队协同开发经验
猜您喜欢 世界多一秒?这对交易员来说是件大事 戏说HTML5 一个经典例子让你彻彻底底理解java回调机制 接口请求利器之Postman 免费试听|一个月搞定面试算法,硅谷工程师传授面试技巧