快的打车移动端架构师 吴更新(Trinea) 这是快的打车移动端架构师、Android 开源项目源码解析 codeKK 发起人 吴更新( @Trinea)在MDCC上分享的内容(略微改动),也是源码解析第一期发布时介绍的源码解析后续会慢慢做的事。从总体设计和原理上对几个图片缓存进行对比,没用到它们的朋友也可以了解它们在某些特性上的实现。(PPT下载地址>>Android开源项目选型之图片缓存) 上篇关于选择开源项目的好处及如何选择开源项目可见: 开源项目使用及选型。 一. 四大图片缓存基本信息 Universal ImageLoader 是很早开源的图片缓存,在早期被很多应用使用。 Picasso 是 Square 开源的项目,且他的主导者是 JakeWharton,所以广为人知。 Glide 是 Google 员工的开源项目,被一些 Google App 使用,在去年的 Google I/O 上被推荐,不过目前国内资料不多。 Fresco 是 Facebook 在今年上半年开源的图片缓存,主要特点包括:
鉴于 Fresco 还没发布正式的 1.0 版本,同时一直没太多时间熟悉 Fresco 源码,后面对比不包括 Fresco,以后有时间再加入对比。 二、基本概念在正式对比前,先了解几个图片缓存通用的概念:
以上概念的称呼在不同图片缓存中可能不同,比如 Displayer 在 ImageLoader 中叫做 ImageAware,在 Picasso 和 Glide 中叫做 Target。 三、共同优点1. 使用简单 2. 可配置度高,自适应程度高 自适应程度高,根据系统性能初始化缓存配置、系统信息变更后动态调整策略。 3. 多级缓存 4. 支持多种数据源 5. 支持多种 Displayer 其他小的共同点包括支持动画、支持 transform 处理、获取 EXIF 信息等。 四、ImageLoader 设计及优点 1. 总体设计及流程上面是 ImageLoader 的总体设计图。整个库分为 ImageLoaderEngine,Cache 及 ImageDownloader,ImageDecoder,BitmapDisplayer,BitmapProcessor 五大模块,其中 Cache 分为 MemoryCache 和 DiskCache 两部分。 简单的讲就是 ImageLoader 收到加载及显示图片的任务,并将它交给 ImageLoaderEngine,ImageLoaderEngine 分发任务到具体线程池去执行,任务通过 Cache 及 ImageDownloader 获取图片,中间可能经过 BitmapProcessor 和 ImageDecoder 处理,最终转换为Bitmap 交给 BitmapDisplayer 在 ImageAware 中显示。 2. ImageLoader 优点(1) 支持下载进度监听 (2) 可以在 View 滚动中暂停图片加载 (3) 默认实现多种内存缓存算法这几个图片缓存都可以配置缓存算法,不过 ImageLoader 默认实现了较多缓存算法,如 Size 最大先删除、使用最少先删除、最近最少使用、先进先删除、时间最长先删除等。 (4) 支持本地缓存文件名规则定义 五、Picasso 设计及优点 1. 总体设计及流程上面是 Picasso 的总体设计图。整个库分为 Dispatcher,RequestHandler 及 Downloader,PicassoDrawable 等模块。 Dispatcher 负责分发和处理 Action,包括提交、暂停、继续、取消、网络状态变化、重试等等。 简单的讲就是 Picasso 收到加载及显示图片的任务,创建 Request 并将它交给 Dispatcher,Dispatcher 分发任务到具体 RequestHandler,任务通过 MemoryCache 及 Handler(数据获取接口) 获取图片,图片获取成功后通过 PicassoDrawable 显示到 Target 中。 需要注意的是上面 Data 的 File system 部分,Picasso 没有自定义本地缓存的接口,默认使用 http 的本地缓存,API 9 以上使用 okhttp,以下使用 Urlconnection,所以如果需要自定义本地缓存就需要重定义 Downloader。 2. Picasso 优点(1) 自带统计监控功能 (2) 支持优先级处理 (3) 支持延迟到图片尺寸计算完成加载 (4) 支持飞行模式、并发线程数根据网络类型而变 (5) “无”本地缓存 六、Glide 设计及优点 1. 总体设计及流程上面是 Glide 的总体设计图。整个库分为 RequestManager(请求管理器),Engine(数据获取引擎)、Fetcher(数据获取器)、MemoryCache(内存缓存)、DiskLRUCache、Transformation(图片处理)、Encoder(本地缓存存储)、Registry(图片类型及解析器配置)、Target(目标)等模块。 简单的讲就是 Glide 收到加载及显示资源的任务,创建 Request 并将它交给RequestManager,Request 启动 Engine 去数据源获取资源(通过 Fetcher ),获取到后 Transformation 处理后交给 Target。 Glide 依赖于 DiskLRUCache、GifDecoder 等开源库去完成本地缓存和 Gif 图片解码工作。 2. Glide 优点(1) 图片缓存->媒体缓存 (2) 支持优先级处理 (3) 与 Activity/Fragment 生命周期一致,支持 trimMemory (4) 支持 okhttp、Volley (5) 内存友好 ② 内存缓存更小图片 ③ 与 Activity/Fragment 生命周期一致,支持 trimMemory ④ 图片默认使用默认 RGB565 而不是 ARGB888 其他:Glide 可以通过 signature 或不使用本地缓存支持 url 过期 七、汇总 三者总体上来说,ImageLoader 的功能以及代理容易理解长度都一般。 Picasso 代码虽然只在一个包下,没有严格的包区分,但代码简单、逻辑清晰,一两个小时就能叫深入的了解完。 Glide 功能强大,但代码量大、流转复杂。在较深掌握的情况下才推荐使用,免得出了问题难以下手解决。 |