Glide源码解析(一):简介

介绍下android开发中常用的图片框架,以及对比他们的优缺点。

UIL

UIL 是一个老牌的图片加载框架,旨在提供一个强大的、灵活的和高度可定制的工具,以实现图像加载、缓存和显示功能。
UIL 支持多线程图片加载,支持占位图和错误图、支持图片下载进度的监听,支持缓存不同尺寸图片,支持图片内存缓存和硬盘缓存,支持自定义图片加载格式,支持 ListView或者 GridView 滚动时暂停加载。但 UIL 不支持动图展示,且该框架的作者已经宣布不在对其进行维护。

1
ImageLoader.getInstance().displayImage(url, imageView, null);

Picasso

Picasso 其名字来源于画家毕加索,是著名开源公司 Square 的作品,与 OkHttp 和 Retrofit 合称开发三件套。Picasso 同样支持占位图和错误图展示,支持图形变换操作,支持内存和硬盘缓存,支持加载本地或者网络资源,比较有特色的是其拥有统计功能,可以知道一共使用了多少内存,缓存命中率, 图片来自内存还是硬盘等。Picasso 使用起来也是简单方便,基本上一行代码可解决显示图片请求。

1
Picasso.with(context)  .load(url).into(imageView);

Glide

Glide 是一个 Google 官方推荐的快速高效的图片加载库,主要目标是让任何形式的图片列表的滚动尽可能地变得更快、更平滑。
Glide 提供了简单易用的API,典型流式语法风格,大部分展示图片需求可以一行代码搞定。Glide 的 API 还特别灵活,在支持开发者自定义配置和模块的同时又和其图片加载图片的逻辑没有任何交集,是一种低耦合的编程方式的实现。默认情况下,通信组件使用 HttpUrlConnection,但也提供了 Volley 和 OkHttp 快速集成的工具。

1
Glide.with(fragment).load(url).into(imageView);

Glide使用了多个步骤来确保在Android上加载图片尽可能的快速和平滑:

  • 自动、智能地下采样(downsampling)和缓存(caching),以最小化存储开销和解码次数;
  • 积极的资源重用,例如字节数组和Bitmap,以最小化昂贵的垃圾回收和堆碎片影响;
  • 深度的生命周期集成,以确保仅优先处理活跃的 Fragment 和 Activity 的请求,并有利于应用在必要时释放资源以避免在后台时被杀掉。

Fresco

Fresco 是一个强大的图片加载组件,其设计中有一个叫做 Image Pipeline 的模块,负责从网络、本地文件系统、本地资源加载图片。为了最大限度节省空间和CPU时间,它含有 3 级缓存设计(2级内存,1级磁盘)。还有一个叫做 Drawees 的模块,它会在图片加载完成前显示占位图,加载成功后自动替换为目标图片。当图片不再显示在屏幕上时,它会及时地释放内存和空间占用。Fresco 包含以下特性:

  • 内存管理:在 Andrid 5.0 以下系统,Fresco 会将图片放到 ASM(Anonymous Shared Memory,匿名共享内存)区域,减少了低性能手机上 OOM 的发生。在图片不用时,应该显式释放这部分资源,SimpleDraweeView 自动处理了这个释放过程。在 5.0 及以上版本系统,由于 Android 对其内存管理做了很大优化,Bitmap 缓存位于 Java 堆区,同样避免了 OOM 的发生。
  • 图片加载:Image Pipeline 允许你用多种方式来定义图片的加载过程图片可以来自远程服务器,本地文件,或者Content Provider,本地资源。压缩后的文件缓存在本地存储中,Bitmap数据缓存在内存中。
  • 图片绘制:可自定义占位图或者进度条,自定义 overlay,现在失败后的点击重试等。
  • 图片渐进式呈现:Android 本身的图片库不支持此格式,但是Fresco支持渐进式图片。渐进式格式先呈现大致的图片轮廓,然后随着图片下载的继续,呈现逐渐清晰的图片,对于移动设备,尤其是慢网络有极大的利好,可带来更好的用户体验。
  • 友好的支持 Gif 图片和 Webp 动图。

共同特性

  • 支持占位图或者加载错误图
  • 支持 图像变换,如 裁剪、尺寸修改、方圆转换等
  • 可配置度高,图片缓存的内存缓存、本地缓存、线程池、缓存算法等大都可轻松配置。
  • 自适应程度高,根据系统性能初始化缓存配置、系统信息变更后动态调整策略。比如根据 CPU 核数确定最大并发数,根据可用内存确定内存缓存大小,网络状态变化时调整最大并发数等。
  • 多级缓存,都至少有二级缓存,提高图片的加载速度
  • 支持多种数据源,如网络、本地、Assets等
  • 支持多种 Displayer,支持自定义的 Displayer 概念。
  • 支持配置图片格式,如配置 ARGB_8888、RGB_565 等

图片格式

不论采用哪个框架,同一张图片其显示质量取决于图片在内存中的格式,与框架无关。这四个框架都支持配置图片格式。格式清晰度从高到低如下:

ARGB_8888 >RGB_565 > ARGB_4444 >ALPHA_8

  • ALPHA_8,代表像素只有透明度信息,没有颜色信息,一个像素占 8 bit,即 1 Byte。
  • RGB_565,代表像素只有颜色信息,没有透明度信息,其中 R 占用 5 bit,G 占用 6 bit,B 占用 5 bit,一个像素大小为 5+6+5=16 bit ,即 2 Byte。
  • ARGB_4444,代表像素既有透明度信息,也有颜色信息,其中 A 占用 4 bit,R 占用 4 bit,G 占用 4 bit,B 占用 4 bit,一个像素大小为 4+4+4+4=16 bit ,即 2 Byte。
  • ARGB_8888,代表像素既有透明度信息,也有颜色信息,其中 A 占用 8 bit,R 占用 8 bit,G 占用 8 bit,B 占用 8 bit,一个像素大小为 8+8+8+8=32 bit ,即 4 Byte。

如何选择图片加载框架

UIL:建议弃用,除非你的项目一直在用 UIL 且框架迁移成本(时间成本)比较大。否则不建议使用或沿用,因为官方已经不再对其维护,且由于不支持动图,若 app 有动图支持的话还需引入其他图片框架,增加应用体积,还不如一步到位。

Picasso:不建议使用,Glide 是 Picasso 的加强版,可以说它的目的就是为了取代 Picasso,所以在 Glide 和 Picasso 之间选择,优先推荐 Glide 。

Glide vs Fresco:这两个框架性能不分伯仲,都可以减少 OOM 的发生。Glide 注重于平滑的滚动,善于处理大型的图片流,Glide还支持播放短视频,有此需求的话 Glide 为不二之选,另外 Glide 还有一个隐藏的优点,它是 Google 官方推荐的框架,所以相对于后期维护成本来说更低一些。Fresco 的优点是内存管理,尤其是在 5.0 以下的系统中优化做的非常好,将图片放在 ASM 中。其缺点也很明显,包的体积太大,其在图片多的应用中更能体现其价值。Fresco 对代码的侵入性可能会更高一些,由于所有的View 组件需要继承自一个基类 DraweeView ,需指定明确尺寸或者用 match_parent 来布局(为了更好的用户体验,解决占位图和真实图尺寸大小不匹配导致UI跳跃的问题),如果你是一个新项目,可以考虑用 Fresco。

总结:框架只在Glide 和 Fresco 中选择,Glide 是 Google 官方推荐的框架,是开发者的首选。如果你对包体积没有要求,且图片需求特别多的情况推荐使用 Fresco。

您的支持是我原创的动力