关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » 安卓开发 »Android ImageLoader框架之基本架构

    Android ImageLoader框架之基本架构

    2015-04-05 00:00:00 出处:Mr.Simple的专栏
    分享

    前言

    在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卡的另一个目录中。这样,整个加载过程也就完成了。

    SimpleImageLoader工程结构图

    效果图

    上述效果中有四张图片是显示不出来的,因为在图片uri列表中有三张是我手机中的图片,模拟器中没有,因此显示加载失败。还有一张是无效的uri,也是加载失败。

    Github仓库地址将在下一篇博客中给出,敬请期待!!

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    帝国CMS7.5编辑器上传图片取消宽高的三种方法

    帝国cms如何自动生成缩略图的实现方法

    Windows 12即将到来,将彻底改变人机交互

    帝国CMS 7.5忘记登陆账号密码怎么办?可以phpmyadmin中重置管理员密码

    帝国CMS 7.5 后台编辑器换行,修改回车键br换行为p标签

    Windows 11 版本与 Windows 10比较,新功能一览

    Windows 11激活产品密钥收集及专业版激活方法

    IT头条

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    严重缩水!NVIDIA将推中国特供RTX 5090 DD:只剩24GB显存

    00:17

    无线路由大厂 TP-Link突然大裁员:补偿N+3

    02:39

    Meta 千万美金招募AI高级人才

    00:22

    技术热点

    windows 7应用程序无法启动出现窗口提示找不到应用程序

    SQL中数据类型转换函数的使用

    MySQL使用变量的注意事项

    SQL Server 锁自定义的示例演示

    如何在Linux命令行中创建以及展示演示稿

    windows 7任务栏显示标题的方法(windows 7任务栏缩略图不显示出

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。