前言
- 图片加载是Android开发中最最基础的功能,同时图片加载OOM也一直困扰着很多开发者,因此为了降低开发周期和难度,我们经常会选用一些图片加载的开源库。
- 老牌的有ImageLoader,UIL,Volley,主流的有,Picasso,Glide,Fresco等等,选择一款好的图片加载裤就成了我们的首要问题。
- 接下来我们对比一下主流的三款 Picasso,Glide,Fresco框架的优缺点。
Picasso,Glide,Fresco的前世今生
基本项对比
对比项 |
Picasso |
Glide |
Fresco |
---|---|---|---|
地址 |
https://github.com/square/picasso |
https://github.com/bumptech/glide |
https://github.com/facebook/fresco |
发布时间 |
2013年5月 |
2014年9月 |
2015年5月 |
是否支持gif |
false |
true |
true |
是否支持webP |
true |
true |
true |
视频缩略图 |
false |
true |
true |
大小 |
100k |
500 KB |
2~3M |
加载速度 |
中 |
高 |
高 |
Disk+Men Cache |
true |
true |
true |
Easy of use |
low |
mediun |
difficult |
star |
13160 |
14709 |
12444 |
开发者 |
Square主导 |
Google主导 |
Facebook主导 |
加载图片耗时及内存对比
without animations
对比项 |
Picasso |
Glide |
Fresco |
---|---|---|---|
java heap/native heap/平均耗时(without animations) |
|
|
|
max java heap |
12.6MB |
11.1MB |
13.9MB |
max native heap |
43.8MB |
43.8MB |
43.8MB |
avg wait time |
241ms |
34ms |
44ms |
从上面的加载静态图片可以看出三大主流框架性能都不错,不过用数据说话整体而言Glide更胜一筹。
allow animations
对比项 |
Picasso |
Glide |
Fresco |
---|---|---|---|
java heap/native heap/平均耗时(allow animations) |
|
|
|
max java heap |
6.8MB |
74.8.1MB |
36.1MB |
max native heap |
18.2MB |
66.8MB |
545.3MB |
avg wait time |
1707ms |
33910ms |
15142ms |
上面的数据我们可以忽略Picasso了,因为它根本不支持gif,那么Glide和Fresco可以看出Fresco的java heap基本保持较低平稳状态,而Glide的java heap基本为Fresco的一倍,所以OOM的风险也比fresco大一倍。 从时间上glide是有一定差距,不过fresco有两张图片没加载完成,所以时间不是完全可靠的数据 从native heap可以看出Fresco最高545MB,这个有点恐怖,下面我们看个知识点。
知识点
- Java Heap是对于Java 虚拟机而说的,一般的大小上限是 16M 24M 48M 76M 具体视手机而定。
- Native Heap是对于C/C++直接操纵的系统堆内存,所以它的上限一般是具体RAM的2/3左右。
- 所以对于2G的手机而言,Java Heap 大概76M,而Native Heap是760M左右,相差10倍。
所以Fresco也是存在一定风险的,因为native heap数据实在是太恐怖了。
详细属性对比
接下来只详细对比Fresco和Glide Picasso从各方面都比这两个弱,这里就不浪费时间了,如果想详细了解的可以看本人之前转载的一篇文章 http://blog.csdn.net/github_33304260/article/details/54140164言归正传
对比项 |
Glide |
Fresco |
---|---|---|
配置 |
compile 'com.github.bumptech.glide:glide:XXX.XXX' |
compile 'com.facebook.fresco:fresco:XXX.XXX |
初始化 |
直接使用 |
Fresco.initialize(this); |
layout |
普通ImageView |
独有的SimpleDraweeView |
圆角, 圆形 |
需要自己实现圆角,继承自BitmapTransformation操作bitmap对象实现 |
通过RoundingParams设置参数 |
缓存 |
Glide内存和磁盘缓存 |
三级缓存,分别是 Bitmap缓存,未解码图片缓存, 文件缓存。 |
缓存图像大小 |
Glide则会根据ImageView控件尺寸获得对应的大小的bitmap来展示,从而缓存也可以针对不同的对象:原始图像(source),结果图像(result) |
缓存原始图像 |
加载策略 |
Glide只有占位图 |
先加载小尺寸图片,再加载大尺寸的 |
加载进度 |
false |
true |
从上面的对比中可以看出来Fresco蛮强大的,不过使用起来相对Glide要复杂一点,而且需要自己的SimpleDraweeView,这一点在切换框架的时候最让人头疼了。而且Glide直接缓存相对大小的图片,节省空间的同时下场如果是同样大小的图片就不要再次请求,直接可以使用。
依赖
Glide
依赖较少
Fresco 要使用完整的Fresco功能就要导入如下的依赖比较多
Glide
Bitmap myBitmap = Glide.with(上下文)
.load(url)
.asBitmap() //必须
.get()
Fresco Fresco要获取bitmap更加复杂, 而且使用起来也并不是那么顺畅。首先,Fresco为了更好地管理bitmap 对象(bitmap对象申请和释放会引起频繁的GC操作,从而引起界面卡顿), 引入了可关闭的引用(CloseableReference), 持有者在离开作用域的时候需要关闭该引用,而我们要获取的bitmap 对象就是可关闭的引用。也就是说,我们不能像上面Glide那样把bitmap 对象取出来传递给其它地方使用, 只能在Fresco提供的作用域范围内使用。 实际项目中会获取缓冲的文件对象:
//同样在DataSubscriber中获取
FileBinaryResource resource = (FileBinaryResource) Fresco.getImagePipelineFactory().getMainFileCache().getResource(new SimpleCacheKey(url));
if (resource != null && resource.getFile() != null) {
setImage(ImageSource.uri(Uri.fromFile(resource.getFile())));
}
优点
Glide
- 多种图片格式的缓存,适用于更多的内容表现形式(如Gif、WebP、缩略图、Video)
- 生命周期集成(根据Activity或者Fragment的生命周期管理图片加载请求)
- 高效处理Bitmap(bitmap的复用和主动回收,减少系统回收压力)
- 高效的缓存策略,灵活(Picasso只会缓存原始尺寸的图片,Glide缓存的是多种规格),加载速度快且内存开销小(默认Bitmap格式的不同,使得内存开销是Picasso的一半)
Fresco
- 最大的优势在于5.0以下(最低2.3)的bitmap加载。在5.0以下系统,Fresco将图片放到一个特别的内存区域(Ashmem区)
- 大大减少OOM(在更底层的Native层对OOM进行处理,图片将不再占用App的内存)
- 适用于需要高性能加载大量图片的场景
缺点
Glide
-没有文件缓存 -java heap比Fresco高
Fresco
- 包较大(2~3M)
- 用法复杂
- 底层涉及c++领域,阅读源码深入学习难度大
结论
Fresco虽然很强大,但是包很大,依赖很多,使用复杂,而且还要在布局使用SimpleDraweeView控件加载图片。相对而言Glide会轻好多,上手快,使用简单,配置方便,而且从加载速度和性能方面不相上下。对于一般的APP来说Glide是一个不错的选择,如果是专业的图片APP那么Fresco还是必要的。
优缺点对比:
Fresco 的讨论一般都是说 Fresco 性能更好,Glide 使用更简单。然而这个问题的答案真的有那么明显吗?
比如性能问题。Fresco 性能真的比 Glide 好多少吗?毕竟 Fresco 包更大,线程开得也更多,图片重采样也要手动提供 ResizeOptions。此外,Fresco 分配用于缓存的内存也更大,如果不是主动指定 Bitmap.Config 否则不会启用 HARDWARE 格式。其中,我最介意的是必须要手动提供 ResizeOptions 才能执行重采样,但往往需要手动执行的都是不靠谱的,如果开发人员素质不够,或者没注意,那么在加载大图时就很容易导致内存问题。
而与此同时,Glide 的使用真的比 Fresco 更简单吗?的确,如果要使用 Java 代码自定义图片请求,那么,Fresco 的确比 Glide 复杂很多。然而,大多数情况下,Fresco 使用 SimpleDraweeView 即可完成图片请求,同时附加圆角、placeholder、宽高比等功能,如果自定义一个通用的 style,Fresco 代码量反而能够比 Glide 少很多。而 Glide 则每次都要 with、load、into,宽高比等功能也要自己实现,圆角的功能也不支持自定义上下左右不同位置使用不同的半径,还要自己创建一个 RoundedCorners 对象,而不是直接设置即可,代码写起来反而更麻烦一些。
总的来说,Fresco 功能更丰富,比如圆角、宽高比、渐进式加载 JPEG、在加载过程中显示进度条、加载失败后点击重试等,对 5.0 以下的手机支持也更好。而 Glide 更方便,比如自动根据 ImageView 尺寸缩放图片、在内存事件回调时自动释放内存等。而对于性能以及使用的问题,答案可能并没有网上讨论的那么简单,还需要自行权衡。
![8499daee72a07667ae8dc6552f33dbd9 8499daee72a07667ae8dc6552f33dbd9](https://blog.75live.com/wp-content/uploads/2023/03/8499daee72a07667ae8dc6552f33dbd9.png)
文章评论