Fresco介绍、Fresco VS Glide多维度对比

一、Fresco概述(来自Fresco官网)

是一个强大的图片加载组件。使用它之后,你不需要再去关心图片的加载和显示这些繁琐的事情!它负责从网络,从本地文件系统,本地资源加载图片并且显示一个占位符直到图片现在完成。它有两个等级的缓存,一个是在内存中,另一个在内部存储。在Android4.x以及更低系统,Fresco 将图片放在Android 内存中的一个特殊区域。 这可以使你的应用程序运行的更快,并且遭受更少的OutOfMemoryError。

Fresco的开源地址是,[https://github.com/facebook/fresco]

Fresco主要模块

1.Image Pipeline

Fresco 中设计有一个叫做 Image Pipeline 的模块。它负责从网络,从本地文件系统,本地资源加载图片。为了最大限度节省空间和CPU时间,它含有3级缓存设计(2级内存,1级磁盘)。

2.Drawees

Fresco 中设计有一个叫做 Drawees 模块,它会在图片加载完成前显示占位图,加载成功后自动替换为目标图片。当图片不再显示在屏幕上时,它会及时地释放内存和空间占用。

二、Fresco特性(来自Fresco官网)

1.内存管理

解压后的图片,即Android中的Bitmap,占用大量的内存。大的内存占用势必引发更加频繁的GC。在5.0以下,GC将会显著地引发界面卡顿。
在Android 4.x以及更低系统,Fresco将图片放到一个特别的内存区域。当然,在图片不显示的时候,占用的内存会自动被释放。这会使得APP更加流畅,减少因图片内存占用而引发的OOM。
Fresco 在低端机器上表现一样出色,你再也不用因图片内存占用而思前想后。

2.图片加载

Fresco的Image Pipeline允许你用很多种方式来自定义图片加载过程,比如:
(1).为同一个图片指定不同的远程路径,或者使用已经存在本地缓存中的图片
(2).先显示一个低清晰度的图片,等高清图下载完之后再显示高清图
(3).加载完成回调通知
(4).对于本地图,如有EXIF缩略图,在大图加载完成之前,可先显示缩略图
(5).缩放或者旋转图片
(6).对已下载的图片再次处理
(7).支持WebP解码,即使在早先对WebP支持不完善的Android系统上也能正常使用!

3.图片绘制

Fresco 的 Drawees 设计,带来一些有用的特性:
(1).自定义居中焦点
(2).圆角图,当然圆圈也行
(3).下载失败之后,点击重现下载
(4).自定义占位图,自定义overlay, 或者进度条
(5).指定用户按压时的overlay

4.图片的渐进式呈现

渐进式的JPEG图片格式已经流行数年了,渐进式图片格式先呈现大致的图片轮廓,然后随着图片下载的继续,呈现逐渐清晰的图片,Android 本身的图片库不支持此格式,但是Fresco支持。

5.动图加载

处理好每一帧并管理好你的内存

三、Fresco具体使用

1.配置环境

compile 'com.facebook.fresco:fresco:0.13.0'

2.Fresco 初始化

Fresco.initialize(context);

3.控件

Fresco 是使用SimpleDraweeView控件来显示图片的。在布局文件中添加SimpleDraweeView控件,代码例如:

<com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/idrawee_view"
        android:layout_width="100dp"
        android:layout_height="100dp" />

注意 记得使用 SimpleDraweeView时
1.宽高要设置为一个具体的值,
2.也可以在代码中设置宽高或者宽高比,但是宽高不能都是 wrap_content。

只有希望显示固定的宽高比时,可以使用wrap_content。
如果希望图片以特定的宽高比例显示,例如 2:1,可以在XML中指定:

fresco:viewAspectRatio="1.5"

四、Fresco VS Glide

1. 功能对比

要从功能上来说, fresco基本满足了所有的网络图片展示需求
在这里插入图片描述

2. 缓存对比

1). Fresco缓存
也是一大亮点, 三级缓存,分别是 Bitmap缓存,未解码图片缓存, 文件缓存。
这里提一点Bitmap缓存:在5.0以下系统,Bitmap缓存位于ashmem,这样Bitmap对象的创建和释放将不会引发GC,更少的GC会使你的APP运行得更加流畅。5.0及其以上系统,相比之下,内存管理有了很大改进,所以Bitmap缓存直接位于Java的heap上。
另外,磁盘缓存还可以通过代码来设置不同手机的缓存容量:

public void initFresco(Context context, String diskCacheUniqueName){
    DiskCacheConfig diskCacheConfig = DiskCacheConfig.newBuilder(context)
            .setMaxCacheSize(DISK_CACHE_SIZE_HIGH)
            .setMaxCacheSizeOnLowDiskSpace(DISK_CACHE_SIZE_LOW)
            .setMaxCacheSizeOnVeryLowDiskSpace(DISK_CACHE_SIZE_VERY_LOW)
            .build();
    ImagePipelineConfig config = ImagePipelineConfig.newBuilder(context)
            .setMainDiskCacheConfig(diskCacheConfig)
            .build();
    Fresco.initialize(context, config);
}

2). Glide缓存
Glide虽然只有内存和磁盘缓存,在性能上比不上Fresco;但他也有另外的优点, Fresco缓存的时候,只会缓存原始图像,而Glide则会根据ImageView控件尺寸获得对应的大小的bitmap来展示,从而缓存也可以针对不同的对象:原始图像(source),结果图像(result); 可以通过.diskCacheStrategy()方法设置:

public enum DiskCacheStrategy {    
  /** Caches with both {@link #SOURCE} and {@link #RESULT}. */    
  ALL(true, true),    
  /** Saves no data to cache. */    
  NONE(false, false),    
  /** Saves just the original data to cache. */    
  SOURCE(true, false),    
  /** Saves the media item after all transformations to cache. */    
  RESULT(false, true);
}

3. bitmap操作

Glide与Picasso类似,通过简单的方法即可获得网络图片的bitmap对象:

Bitmap myBitmap = Glide.with(applicationContext)  
    .load(yourUrl)  
    .asBitmap() //必须  
    .centerCrop()  
    .into(500, 500)  
    .get()

相反,Fresco要获取bitmap更加复杂, 而且使用起来也并不是那么顺畅。首先,Fresco为了更好地管理bitmap 对象(bitmap对象申请和释放会引起频繁的GC操作,从而引起界面卡顿), 引入了可关闭的引用(CloseableReference), 持有者在离开作用域的时候需要关闭该引用,而我们要获取的bitmap 对象就是可关闭的引用。也就是说,我们不能像上面Glide那样把bitmap 对象取出来传递给其它地方使用, 只能在Fresco提供的作用域范围内使用,代码如下:

public void setDataSubscriber(Context context, Uri uri, int width, int height){
    DataSubscriber dataSubscriber = new BaseDataSubscriber<CloseableReference<CloseableBitmap>>() {
        @Override
        public void onNewResultImpl(
                DataSource<CloseableReference<CloseableBitmap>> dataSource) {
            if (!dataSource.isFinished()) {
                return;
            }
            CloseableReference<CloseableBitmap> imageReference = dataSource.getResult();
            if (imageReference != null) {
                final CloseableReference<CloseableBitmap> closeableReference = imageReference.clone();
                try {
                    CloseableBitmap closeableBitmap = closeableReference.get();
                    Bitmap bitmap  = closeableBitmap.getUnderlyingBitmap();
                    if(bitmap != null && !bitmap.isRecycled()) {
                        //you can use bitmap here
                    }
                } finally {
                    imageReference.close();
                    closeableReference.close();
                }
            }
        }
        @Override
        public void onFailureImpl(DataSource dataSource) {
            Throwable throwable = dataSource.getFailureCause();
            // handle failure
        }
    };
    getBitmap(context, uri, width, height, dataSubscriber);
}

在实际使用过程中, 如果只有在作用域范围操作bitmap,明显不能满足需求。
项目中使用的方式是获取缓存的文件对象:

//同样在DataSubscriber中获取
FileBinaryResource resource = (FileBinaryResource) Fresco.getImagePipelineFactory().getMainFileCache().getResource(new SimpleCacheKey(url));
if (resource != null && resource.getFile() != null) {           
    setImage(ImageSource.uri(Uri.fromFile(resource.getFile())));
}

4. Fresco特有

除了以上内容,Fresco还具备以下一些常用的,但Glide没有的功能:
1,SimpleDraweeView控件可以指定图片的宽高比例(app:viewAspectRatio),对于手机适配非常重要;
2,图片加载进度;
3,先加载小尺寸图片,再加载大尺寸的(Glide只有占位图);

5. 性能对比

除了在功能上对比, 网络图片显示是非常耗性能的, 下面就针对图片质量,内存使用等情况来对比。

1). 图片显示质量
Glide的图片质量不如Fresco, 原因是Glide为了省内存, 采用了RGB_565的格式显示图片, 相对于”ARGB8888”要省了将近一半的内存。但也可以通过代码将图片格式改为ARGB_8888。

2). 加载图片速度

Fresco设计中有个有一个image pipeline模块, 可以最大限度节省网络下载图片, 在不考虑缓存的情况下, Fresco也比Glide快很多。 在demo中,同时加载上述图片, Fresco需要3s左右, Glide需要5s左右。

3). 内存使用情况

加载同一张图内存使用情况
情况1(控件比图片大)
情况2(控件比图片小)

当控件比较小的时候, Glide明显比情况1使用的内存少很多, 而Fresco则几户与情况1使用相同内存。因为Fresco在没有做过任何处理的情况下,会将原图片加入到内存中,然后做一些压缩处理显示在控件上; 而Glide则是直接准确获取了控件大小,然后得到一张与控件大小相当尺寸的图片,加载到内存并显示。

情况2当时在第一次引入Fresco的碰到过,有些高质量的图片显示在小尺寸的控件上,直接显示的话,很容易出现图片显示不出的情况。

Fresco也提供了方法将图片尺寸压缩,我们可以得到控件的宽高,然后进行压缩:

虽然可以解决内存溢出,不必要的内存消耗等情况,但是这样做的前提是必须提前知道控件的宽高,当图片控件使用了wrap_content等方式,这样做就会比较繁琐了。

而Glide则无需考虑这个问题。

4). 引申问题

Glide虽然在需要压缩问题上有优势,但也有另外一个问题, 缓存, 例如上述“情况2”加载了图片在小的控件上, Glide会将300*300的图片保存在缓存中,而当下次需要展现“情况1”(800x600)的时候, 会再次从网络中获取。

要解决这个问题, 需要另外进行缓存控制(参考上述 缓存):

.diskCacheStrategy(DiskCacheStrategy.ALL)

6. 总结

Fresco和Glide还有更强大的更灵活的功能,例如: Fresco可以自定义网络加载,与其它的Image Loader配合使用等等。

常用情况选择Glide. 选择的原因如下:

  1. Glide默认提供配置支持本地图片缓存,缓存的机制是DiskLruCache.可以根据自己的需要,自定义图片缓存的路径.所以在考虑节省用户流量来看可以不考虑Picasso;
  2. 虽然Fresco也提供更强大的图片缓存和加载机制,不过在比较之后,感觉Fresco还是有待完善.Glide可以很简单的获取网络图片的Bitmap对象,而Fresco需要通过订阅数据源克隆Bitmap对象的引用才能存储值.操作方式不够简洁和友好;
  3. Fresco的库文件中,以最新的0.8.1为例,imagepipeline-0.8.1.aar光包得大小就有3.5M而Glide包的大小为465K为了让Apk包得体积更小,所以考虑使用Glide。

五、写在最后

此文章为个人开发时记录,有时时间有限,无法深入研究,若看到此文章后有其他见解或解决方式,欢迎留言交流👇👇👇

参考链接:
https://www.dandelioncloud.cn/article/details/1548106913728442370
https://www.dandelioncloud.cn/article/details/1438138574574276609

————————————————
版权声明:转载请附上原文出处链接及本声明。
原文链接:
[https://blog.csdn.net/weixin_44158429/article/details/129842086]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值