图片

Glide 系列(一) 图片加载框架对比

2018-03-19  本文已影响267人  嘎啦果安卓兽

本文主要比对框架包括:Universal Imageloader(下文简称 UIL)、Picasso、 Glide、Fresco。先对各个框架做简单介绍,再对框架进行对比。

简介篇

UIL

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

ImageLoader.getInstance()
.displayImage("http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg", ivImg, null);
Picasso

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

Picasso.with(context)  
 .load("http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg")
 .into(ivImg); 
Glide

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

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

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

生命周期的集成也是 Glide 的一大特色。

Fresco

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

Fresco 包含以下特性:

Fresco 使用时需要用其框架定义的组件,且明确指定尺寸 或者用 match_parent 标注。

<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/my_image_view"
    android:layout_width="130dp"
    android:layout_height="130dp"
    fresco:placeholderImage="@drawable/my_drawable"
  />
Uri uri = Uri.parse("https://raw.githubusercontent.com/facebook/fresco/gh-pages/static/logo.png");
SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view);
draweeView.setImageURI(uri);

对比篇

共同特性
对比表格
对比图.png
磁盘缓存

我们先啰嗦两句,来看一下存储器的层次结构,简单分为:寄存器、高速缓存、主存、本地磁盘。


存储器层次模型.jpg

此图由上到下数据访问速度在逐层降低,从内存读取数据的速度远远大于从硬盘读取数据,从硬盘读取数据的速度远远大于从网络访问数据的速度,且网络访问还有可能失败。寄存器、高速缓存这两层对于我们 app 开发者来说是透明的,无需考虑,我们只需将内存缓存和硬盘缓存利用起来就可以了。基本上所有的图片加载框架都是在内存和硬盘这两个层次上做的数据缓存。内存缓存作为第一级缓存,可以避免将同一张图片重复加载到内存;硬盘缓存作为第二级缓存,可以避免重复下载同一张网络图片。

我们知道 ImageView 在显示图片时只是起一个容器的作用,里面放置的图片是 一个由像素组成的二维矩阵。既然是一个容器,那图片大小可能大于容器,也可能小于容器,所以才有了 ImageView 的 scaleType 属性。当图片大于容器时,可以将图片压缩,裁剪;当图片小于容器时既可以放大填充容器,也可以不做任何事情。且图片在硬盘中的大小并不等于在内存中的大小。图片在内存中的大小取决于其编码格式。许多图片加载框架会根据 ImageView 大小对图片做缩略处理,这样既保证了清晰度又减少了内存耗用。

全尺寸 指 url 对应的图片,实际尺寸为 ImageView 尺寸相同的图片。对于 Picasso,不管 ImageView 如何变换大小,只会缓存一个全尺寸的图片。对于 Glide、UIL、Fresco 都支持缓存同一图片的不同尺寸。对同一张图片缓存不同尺寸意味着需要更大的缓存空间,但同时也能提供了更快的展示速度,此处就是用空间换取时间,省去了每次显示之前将图片重新调整大小的时间。所以缓存多尺寸的图片框架会相较于缓存原始尺寸的更加快,但由于占据了更多的空间,这一点可以按需设置。

图片格式

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

ARGB_8888 >RGB_565 > ARGB_4444 >ALPHA_8

附:在这对图片格式做一个简单介绍:其中 A,代表透明度;R,代表 Red, 红色;G,代表 Green,绿色;B,代表 Blue,蓝色。

这几个字段在 Android 源码 Bitmap.Config 有中定义,可以看到 ARGB_8888 格式 是占用空间最大的,一个像素点要占用 4 Byte 内存,由于保存了更多的图片细节信息,所以此格式也是显示图片最清晰的。ARGB_4444 和 RGB_565 占用内存为 ARGB_8888 的一半。ARGB_4444 虽然设计理念是为了保留透明度的同时又节省内存,但由于其显示的图像质量太差而遭到弃用。RGB_565 和 ARGB_8888 是最为通用的两种图片格式,可以按需选取。如果必须保留图片的透明度信息,则建议使用 ARGB_8888, 如果APP 内存吃紧同时对透明度没有要求的话,可使用 RGB_565。

包体积

UIL 和 Picasso 包体积较小,对安装包影响不大。
Glide 包体积略大,其功能十分强大,内部实现及其复杂,其方法数较多,使用时可能会遇到 65k 问题。
Fresco 包体积很大,若按照正确步骤使用了 Fresco,引入后发布包的体积应当不会增加 500Kb。用户可以根据自己需求有选择的添加动画依赖库和 WebP 支持包,这种模块化机制使得基础 Fresco 库很轻,增加一个库大约包体积会增加 100 KB。

如何选择图片加载框架

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。

附:

http://blog.csdn.net/zivensonice/article/details/51822968
http://www.mamicode.com/info-detail-929571.html
这两个链接是对各个框架加载图片时堆内存、本地内存、加载时间、请求次数的对比,有兴趣的可以自己参考下。笔者个人感觉参考性不是很大,在多个机型测试结果不稳定,及同机型上框架切换时数据变化慢。现在 Android Studio 3.0 版本有 Android Profiler,可以点开观察内存情况,这个只支持5.0版本以上的手机哦。

参考文献

https://www.fresco-cn.org/
https://github.com/bumptech/glide/wiki
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0327/2650.html

上一篇 下一篇

猜你喜欢

热点阅读