教你写Android ImageLoader框架之基本架构 .

前言

在Android开发中,ImageLoader应该算得上是最重要的开源库之一,由于项目原因(不能使用开源库),前段时间自己也是需要实现一个简单的ImageLoader,因此诞生了这个库,我们暂且叫它为SimpleImageLoader。就目前而言,你上网查ImageLoader资料的时候,基本上能够找到很简单的实现,基本上一个类就把所有的工作给做了,这就显得很不专业了嘛,很多时候我们不只是需要实现功能,而是希望能够在实现功能的同时在设计层面有所提升。

SimpleImageLoader分享出来的主要目的并不是说替代那些著名开源库,而是提供一个简单的、又有一定参考价值的ImageLoader实现让一些需要帮助的人学习,在深入了解实现的同时学到知识,也能够体会到在设计一个开源库时应该要做哪些考虑、做哪些取舍、有什么模式,当然在了解了ImageLoader的实现之后再去使用专业的开源库也会更加的得心应手,出现问题的时候自己也能够不太费力地去究其原因。在提升自己的同时也能够了解一些开源库的设计基本原则,这也是我的博客中一直主张的观点。

当然限于本人水平有限,有bug在所难免,但是我们这里是以学习为目的,了解ImageLoader的设计与实现才是我们最重要的目的,一些细节不必在意,可以在你深入的学习过程中修改你认为不合理或者错误的地方。如果你有好的实现方法或者有好的建议,也都请指教一二;如果你认为我写的东西烂得不值一提,那你就深深地埋藏在心里吧。

 

基本架构      

一般来说,ImageLoader的实现都是基于线程池,在第一版的我也是使用线程池来加载图片,但是后面的版本却换成了跟SimpleNet类似的架构模式,原因是觉得线程池刚启动的时候会稍微慢一些,我感觉不太爽就换了线程模型。当然我也会把线程池的版本在另外的分支上给出,这样给一些需要的朋友参考。
SimpleImageLoader的基本结构如图1所示。
 
 

技术分享

图1

看到这幅图看过SimpleNet网络框架的朋友应该是会熟悉一些,基本结构与SimpleNet很相似,其实主要也是我们比较喜欢把架构图画成这种分层样式,感觉比较好理解,

SimpleImageLoader类是用户的入口,用户在通过配置类初始化SimpleImageLoader之后就可以向SimpleImageLoader提交加载图片的请求了。SimpleImageLoader内部维护了一个请求队列,用户提交的加载图片的请求会在内部被封装成BitmapRequest对象,然后将这些对象放到请求队列中。在创建队列时会创建用户指定数量(默认为CPU个数 + 1)的线程来加载图片,这些线程在内部命名为RequestDispatcher,它们在run函数中不断地获取队列中的加载请求,然后交给对应的Loader加载图片。

为了方便用户的扩展,我们引入了Loader这个抽象,因为在SimpleImageLoader中只支持两种图片uri的加载,即网络图片uri和本地文件的uri。网络图片一般以"http://"或者"https://"开头,而本地图片的uri格式却是"file://"开头,SimpleImageLoader内部通过图片uri的格式的不同使用不同的Loader来加载图片,这样后续用户就可以注册Loader来实现其他格式的加载,例如"drawable:// + 图片名"来加载res/drawable中的图片等。这样保证了SimpleImageLoader可加载图片uri格式的可扩展性。Loader会通过LoaderManager来进行管理,如果需要注册自己的Loader实现,则调用LoaderManager的register函数即可。如果你传递进去的图片uri是无效,例如格式错误,那么LoaderManager会返回一个默认的Loader,这个默认的Loader名为NullLoader,它其实什么也不做,只是为了防止在外部进行判空而已,这种模式成为Null Object设计模式。当然,在加载图片之前我们会从缓存中读取,如果有缓存我们则不加载。

Loader加载完图片之后会先更新UI,即将图片显示到对应的ImageView上,在构造BitmapRequest时内部已经将图片的uri设置为ImageView的tag了。图片加载完成后判断ImageView的tag和uri是否相等,如果相等则将图片显示到ImageView上,否则不更新ImageView。这一步很重要,很多朋友在使用ImageLoader时出现问题基本上就是由于没有设置ImageView的tag。

加载图片的先后顺序是由加载策略决定的,策略相关的内容没有在架构图中给出。加载策略决定了请求在队列中的排序,在将请求添加到队列中时会给每个请求设置一个序号,队列将根据这个序号对请求进行排序。这样我们就可以知道哪个请求是先添加进来的,也可以很方便的实现自己的策略类来定制自己的加载策略,比如最后加载到队列中的请求最先加载。比如我们在ListView滚动时,最后添加到队列中的图片请求应该是我们最急需显示的,我们它们就在手机的当前屏幕,而前面的请求对应的ImageView已经被复用,即使它们加载完成它们也不会被显示,因为ImageView的tag已经变化了。因此,策略的灵活性依然很重要。

在加载完图片并且更新UI之后,我们会将图片缓存起来。内置的缓存类型有四种,无缓存、内存缓存、sd卡缓存、内存和sd卡的双缓存,这四种缓存都实现了Cache接口,如果你这四种缓存类型还不能满足你的需求,那么你可以实现Cache接口,然后实现自己的缓存逻辑,然后在配置ImageLoader时设置需要的缓存类型(具体配置后续说明),如果不配置则默认使用的是内存缓存。这里我们又看到了一个面向接口编程的例子,即SimpleImageLoader只依赖于Cache接口的抽象,而不是说依赖于某个具体的缓存类,这样用户就可以很方面的实现自己的缓存逻辑,并且将缓存实现注入到sdk中。当然,上述的Loader、加载策略实现也是基于同样的理论基础,就是说过很多遍的“面向接口编程”。

恩,是时候捋一捋这个执行流程了。

用户调用displayImage请求加载图片,SimpleImageLoader将这个加载图片请求封装成一个Request,然后加入到队列中。几个色眯眯的调度子线程不断地从队列中获取请求,然后根据uri的格式获取到对应的Loader来加载图片。在加载图片之前首先会查看缓存中是否含有目标图片(具体细节在后续的博客再细说),如果有缓存则使用缓存,否则加载目标图片。获取到图片之后,我们会将图片投递给ImageView进行更新,如果该ImageView的tag与图片的uri是一样的,那么则更新ImageView,否则不处理。使用ImageView的tag与图片的uri进行对比是为了防止图片错位显示的问题,这在ImageLoader中是很重要的一步。如果目标图片没有缓存,第一次从uri中加载后会加入缓存中,当然从sdcard中加载的图片我们只会缓存到内存中,而不会再缓存一份到sd卡的另一个目录中。这样,整个加载过程也就完成了。


http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQsR3ar6XbQ1w%3D%3D
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSb%2B%2B7aupBqNg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdS%2ByG7gI4noFw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSAV3NjX5MjXw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQKk0%2BW%2Bwra1Q%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTwID%2BhOCWc3g%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQ2zV1Ov%2FlS1Q%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTH9PLBBCxd3w%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdRHUnt8nzLOVw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTEL6bmF9Oe8g%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQjMOuQufBuog%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQQ9wka%2B0ctPg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTl9LybhdI2JA%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQ2Gn6LMuOr9A%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTfDv5S7UuMJA%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTlb%2FqW8m6apw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTLaH%2B8eHGE%2FQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTavDaQWXEHdw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSa2n99yJfFgw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTg97j9MZ%2FvLQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSxx5KKPJiSUQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdRn8oHz4a%2Ba%2Fg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTYljB8Zts5rw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSHfKz0KsjYvA%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSHfKz0KsjYvA%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdS4Bf5K%2BaMVmg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSNzd5FTEAjaQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdToCKoo7Aq5iw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdRLo%2FpDoBp73Q%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdT1iXfqTTMpwQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQMCqMEdGtWEg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQiJsdeDKgAQg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSNA0TtWM2b0g%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTSKxssiAn4Zg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTP%2FB5%2FnWu58Q%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQMtntGdyGEdA%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTjvy2XSrpZsg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdS91Y%2FMaVqXnw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTJRwz0ZUT7Qw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTxhcJzegqnuQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTkEYp5p7ckGw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdT8WgBFXHkHxg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdRg8BdMz4uQGA%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTPQ3qRqTfW%2BA%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTK7MN%2FnKaXgw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSSRouowWE2EA%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTdVx71Vz2sXQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSab1sufaIgmg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdR%2FRngOapYsog%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSAJU2612asLw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTW5CR%2B6YTkJQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdRpvJPbLzJKiw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdRscBQAdu4bLg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdT%2B1DvFi3oUFg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdRvxuRi93uK2A%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQghSB5kAUZTg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdT3f3dWI2riRw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTSCCP%2FYNZl4g%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSffnsCIMEgaw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTWDj%2BFxoTCFQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdRYRw41S%2FhNzQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQcGzHcDgIEkg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQ8d5xtXW8kSQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTocO07p3sfEw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQGq2SJmKwXMQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQRlmfoBBjPUw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQQN3NSMFwjbA%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdRd5uI5PUyGIw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSnzsGXEnOWkA%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSmUY6qVK7xVQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTtI7hDivyOdg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdRetzDFpiB%2Bzw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdRKGWWIiUE8ww%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSY6Az1ESCkJA%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdS%2FisBLN4JuvQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTtlhnP4DNf4A%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdR69mg1Ro2k%2Bg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSpbExM4vm81g%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTSTjyPoulqqg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSYF8KVtQQuww%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQjh0sH64qRvQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSgRNuKqn3eDg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSLz453FjE%2BHg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQQhSZzEJZ2cg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQ76VXY1dacNQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdS8p7lcoPVDHQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdT1ZDyKTcqbbw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdS8HipIqcbTTw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSjPH%2FEHkCOww%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTWoP%2F3phuDxA%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSZuH2jGVyupQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQ%2FAnKOjR7%2FYw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdT6lQw8SdLB7g%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTnEkqYLT1wCw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdRm%2BN%2BDyjeKyw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQMvUfOr1u%2BPw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSTjoysZfZ2Bg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQSMWLz%2BLu6ZA%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSNHDkVkcNWHg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTzWMyUavjAkw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTrPSalz%2FikCw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTFgEm2BI9zow%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdS3vk6UXGZtBQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdRCusT3W7%2B%2FOA%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdRQsGX8KKOhww%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdT4ST8vzkEZSQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQkU%2BI2E25Sxw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdT7Lh5ZjvoumQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQtFCScPWY1yg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTyHvMoqOuFWA%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSC5Qx1bj10Kw%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdQz50M3F5LKZQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTlzTdWyOLkXQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdRBs8M6w3j8dg%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSyIr1Bbb5mUQ%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdTmhYygZW970Q%3D%3D&as=new
http://tinypic.com/useralbum.php?ua=Ivdn0kUPpdSqGcNo2JJy7w%3D%3D&as=new

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。