Fresco图片框架

使用Frasco需要使用的依赖:

implementation 'com.facebook.fresco:fresco:1.9.0'
// 支持 GIF 动图,需要添加
implementation 'com.facebook.fresco:animated-gif:1.9.0'

Url资源:

//url资源:
public static final String mImageUrl =
        "http://pic39.nipic.com/20140226/18071023_164300608000_2.jpg";
public static final String mErrorUrl =
        "http://pic39.nipic.com/20140226/18071023_1643006080dddd00_2.jpg";
public static final String mGifUrl =
        "http://img.zcool.cn/community/0139505792e5fc0000018c1bbb7271.gif";

Fresco是什么

  • Fresco是一个强大的图片加载组件。
  • Fresco中设计有一个叫做“Image Pipeline”的模块。它负责从网络,从本地文件系统,本地资源加载图片。为了最大限度节省空间和CPU事件,它含有3级缓存设计(2级缓存、1级文件)。
  • Fresco 中设计有一个叫做*Drawees*模块,方便地显示loading图,当图片不再显示在屏幕上时,及时地释放内存和空间占用。
  • Fresco 支持 Android2.3(API level 9) 及其以上系统。
  • 支持的图片格式:PNG,GIF,WebP, JPEG
  • 它内部用了大量的建造者模式、单例模式、静态工厂模式、生产/消费者模式。内部实现比较复杂,就拿图片加载来说,是通过在异步线程中回调图片的输入流,然后通过一系列读取、写入、转化成EncodedImage,然后再Decode成Bitmap,通过Handler转给UI线程显示,通过IO操作存储在硬盘缓存目录下。

 

三大核心部分:

  • DraweeView

继承于 View, 负责图片的显示。
一般情况下,使用 SimpleDraweeView 即可

  • DraweeHierarchy

Dra于weeHierarchy 用于组织和维护最终绘制和呈现的 Drawable 对象,相当MVC中的M。

  • DraweeController

 

三级缓存:

  • Bitmap缓存

      Bitmap缓存存储Bitmap对象,这些Bitmap对象可以立刻用来显示或者用于后处理。

      在5.0以下系统,Bitmap缓存位于ashmem,这样Bitmap对象的创建和释放将不会引发GC,更少的GC会使你的APP运行得更加流畅。【匿名共享内存】

      5.0及其以上系统,相比之下,内存管理有了很大改进,所以Bitmap缓存直接位于Java的heap上。

      当应用在后台运行时,该内存会被清空。

  • 未解码图片的内存缓存

      这个缓存存储的是原始压缩格式的图片。从该缓存取到的图片在使用之前,需要进行解码。

  • 磁盘缓存

      和未解码的内存缓存相似,和磁盘缓存不一样,APP在后台时,内容是不会被清空的。即使关机也不会。用户可以随时用系统的设置菜单中进行清空缓存操作。

、Drawees 不支持 wrap_content 属性。如果使用也需要宽和高一个是固定值。然后使用属性宽高比

 

常用属性:

<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/my_image_view"
    android:layout_width="20dp"
    android:layout_height="20dp"
    fresco:fadeDuration="300"
    fresco:actualImageScaleType="focusCrop"
    fresco:placeholderImage="@color/wait_color"
    fresco:placeholderImageScaleType="fitCenter"
    fresco:failureImage="@drawable/error"
    fresco:failureImageScaleType="centerInside"
    fresco:retryImage="@drawable/retrying"
    fresco:retryImageScaleType="centerCrop"
    fresco:progressBarImage="@drawable/progress_bar"
    fresco:progressBarImageScaleType="centerInside"
    fresco:progressBarAutoRotateInterval="1000"
    fresco:backgroundImage="@color/blue"
    fresco:overlayImage="@drawable/watermark"
    fresco:pressedStateOverlayImage="@color/red"
    fresco:roundAsCircle="false"
    fresco:roundedCornerRadius="1dp"
    fresco:roundTopLeft="true"
    fresco:roundTopRight="false"
    fresco:roundBottomLeft="false"
    fresco:roundBottomRight="true"
    fresco:roundWithOverlayColor="@color/corner_color"
    fresco:roundingBorderWidth="2dp"
    fresco:roundingBorderColor="@color/border_color"
    />

使用代码:

GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(getResources())
                //设置占位图及它的缩放类型
                .setPlaceholderImage(ContextCompat.getDrawable(this, R.mipmap.icon_placeholder),
                ScalingUtils.ScaleType.FOCUS_CROP)
                //设置正在加载图及其缩放类型
                .setProgressBarImage(ContextCompat.getDrawable(this, R.mipmap.icon_progress_bar),
                ScalingUtils.ScaleType.FOCUS_CROP)
                //设置失败图及其缩放类型
                .setFailureImage(ContextCompat.getDrawable(this, R.mipmap.icon_failure),
                ScalingUtils.ScaleType.FOCUS_CROP)
                //设置重试图,它默认的缩放类型是CENTER_INSIDE
                .setRetryImage(ContextCompat.getDrawable(this, R.mipmap.icon_retry))
                //构建
                .build();
        //设置GenericDraweeHierarchy
        sdv.setHierarchy(hierarchy);
        //开始下载
        sdv.setImageURI(imageUrl);
        //构建Controller
        DraweeController controller = Fresco.newDraweeControllerBuilder()
                //设置点击重试是否开启
                .setTapToRetryEnabled(true)
                //构建 
                .build();
        //设置Controller
        sdv.setController(controller);
        // 功能:设置渐进式
        ImageRequest imageRequest =
        ImageRequestBuilder.newBuilderWithSource(Uri.parse(mJpegUrl))
        .setProgressiveRenderingEnabled(true)
        .build();
        // 功能:设置圆角或者边框
 RoundingParams roundingParams = new RoundingParams();
       
        roundingParams.setBorderColor(ContextCompat.getColor(this,R.color.colorAccent));
        roundingParams.setBorderWidth(20);
        roundingParams.setCornersRadius(180);
        genericDraweeHierarchy.setRoundingParams(roundingParams);
        // 功能:Gif动画
              .setAutoPlayAnimations(true)   //自动播放
        // 功能:下载进度
        ControllerListener controllerListener = new BaseControllerListener<ImageInfo> () {
    @Override
    public void onFinalImageSet()
      
        };
    .setControllerListener(imageInfoBaseControllerListener)

注意:1、setHierarchy() 2、setImageURI () 3、setController()
               顺序不能乱,不然出不来重试

          2、 就算我们设置了自动旋转属性,那么进度图也不可能旋转;只有进度图和自动旋转属性都在XML中声明出来,才可以让进度图旋转。

 

缩放类型—ScaleType:推荐使用:focusCrop 类型

类型描述
center 居中,无缩放。
centerCrop 保持宽高比缩小或放大,使得两边都大于或等于显示边界,且宽或高契合显示边界。居中显示。
focusCrop 同centerCrop, 但居中点不是中点,而是指定的某个点。
centerInside缩放图片使两边都在显示边界内,居中显示。和 fitCenter 不同,不会对图片进行放大。如果图尺寸大于显示边界,则保持长宽比缩小图片。
fitCenter

保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,且宽或高契合显示边界。居中显示。

fitStart 同上。但不居中,和显示边界左上对齐。
fitEnd 同fitCenter, 但不居中,和显示边界右下对齐。
fitXY 不保存宽高比,填充满显示边界。
none 如要使用tile mode显示, 需要设置为none
XML属性 意义
fadeDuration 淡入淡出动画持续时间(单位:毫秒ms)
actualImageScaleType 实际图像的缩放类型
placeholderImage 占位图
placeholderImageScaleType 占位图的缩放类型
progressBarImage 进度图
progressBarImageScaleType 进度图的缩放类型
progressBarAutoRotateInterval 进度图自动旋转间隔时间(单位:毫秒ms)
failureImage 失败图
failureImageScaleType失败图的缩放类型
retryImage重试图
retryImageScaleType 重试图的缩放类型
backgroundImage背景图
overlayImage 叠加图
pressedStateOverlayImage 按压状态下所显示的叠加图
roundAsCircle 设置为圆形图
roundedCornerRadius 圆角半径
roundTopLeft 左上角是否为圆角
roundTopRight 右上角是否为圆角
roundBottomLeft 左下角是否为圆角
roundBottomRight 右下角是否为圆角
roundingBorderWidth 圆形或者圆角图边框的宽度
roundingBorderColor 圆形或者圆角图边框的颜色
roundWithOverlayColor 圆形或者圆角图底下的叠加颜色(只能设置颜色)
viewAspectRatio 控件纵横比

webp介绍:

  WebP文件格式和JPEG类似,也是通过牺牲图片质量来降低图片文件大小,但能在相同质量的情况下
比JPEG文件尺寸小巧许多。目前的Chrome应用商店图片已全部转换为WebP格式。虽说WebP格式有各
种优点,但支持甚少是最大的问题;

自定义缓存地址:

// fresco的初始化     DiskCacheConfig  /    ImagePipelineConfig
DiskCacheConfig diskCacheConfig = DiskCacheConfig.newBuilder(this)
        // 设置滴定仪缓存路径
        .setBaseDirectoryPath(getCacheDir())
        .build();

ImagePipelineConfig config = ImagePipelineConfig.newBuilder(this)
        //将DiskCacheConfig设置给ImagePipelineConfig
        .setMainDiskCacheConfig(diskCacheConfig)
        .build();       // 在Application中配置

// 初始化Fresco,自定义ImagePipeline的属性
Fresco.initialize(this, config);

Fresco性能上的优点:

  • 优一:

       1、支持webp格式的图片,是Google官方推行的,它的大小比其它格式图片的大小要小一半左右,使用该格式最大的优点就是轻量、省流量、图片加载迅速。而Fresco是通过jni来实现支持WebP格式图片。

  • 优二:

       2、5.0以下系统:使用”ashmem”(匿名共享内存)区域存储Bitmap缓存,这样Bitmap对象的创建、释放将永远不会触发GC,关于”ashmem”存储区域,它是一个不在Java堆区的一片存储内存空间,它的管理由Linux内核驱动管理,不必深究,只要知道这块存储区域是别于堆内存之外的一块空间就行了,且这块空间是可以多进程共享的,GC的活动不会影响到它。5.0以上系统,由于内存管理的优化,所以对于5.0以上的系统Fresco将Bitmap缓存直接放到了堆内存中。

       Fresco中采取的办法则是使用引用计数的方式,其中有一个SharedReference这个类,这个类中有这么两个方法:addReference()和deleteReference(),通过这两个基本方法来对引用进行计数,一旦计数为零时,则对应的资源将会清除(如:Bitmap.recycle()等),而Fresco为了考虑更容易被我们使用,又提供了一个CloseableReference类,该类可以说是SharedReference类上功能的封装,CloseableReference同时也实现了Cloneable、Closeable接口,它在调用.clone()方法时同时会调用addReference()来增加一个引用计数,在调用.close()方法时同时会调用deleteReference()来删除一个引用计数,所以在使用Fresco的使用,我们都是与CloseableReference类打交道,使用CloseableReference必须遵循以下两条规则:

            1、在赋值CloseableReference给新对象的时候,调用.clone()进行赋值

            2、在超出作用域范围的时候,必须调用.close(),通常会在finally代码块中调用

?

1 2 3 4

56 7 8

<code class="hljs cs">void gee() { CloseableReference<val> ref = foo();

try { haa(ref); } finally { ref.close(); } }</val></code>

遵循这些规则可以有效地防止内存泄漏。

优三:

3、使用了三级缓存:Bitmap缓存+未解码图片缓存+硬盘缓存。

其中前两个就是内存缓存,Bitmap缓存根据系统版本不同放在了不同内存区域中,而未解码

图片的缓存只在堆内存中,Fresco分了两步做内存缓存,这样做有什么好处呢?第一个好处

就如上的第二条,第二个好处是加快图片的加载速度,Fresco的加载图片的流程为:查找

Bitmap缓存中是否存在,存在则直接返回Bitmap直接使用,不存在则查找未解码图片的缓

存,如果存在则进行Decode成Bitmap然后直接使用并加入Bitmap缓存中,如果未解码图片缓

存中查找不到,则进行硬盘缓存的检查,如有,则进行IO、转化、解码等一系列操作,最后

成Bitmap供我们直接使用,并把未解码(Encode)的图片加入未解码图片缓存,把Bitmap加

入Bitmap缓存中,如硬盘缓存中没有,则进行Network操作下载图片,然后加入到各个缓存

中。

既然Fresco使用了三级低的情况缓存,而有两级是内存缓存,所以当我们的App在后台时或

者在内存下在onLowMemory()方法中,我们应该手动清除应用的内存缓存,我们可以使用下

面的方式:

?

1 2 3 4

56 7 8

<code class="hljs avrasm"> ImagePipeline imagePipeline = Fresco.getImagePipeline();//清空

内存缓存(包括Bitmap缓存和未解码图片的缓存) imagePipeline.clearMemoryCaches(); //清空硬盘缓存,

一般在设置界面供用户手动清理 imagePipeline.clearDiskCaches(); //同时清理内存缓存和硬盘缓存

imagePipeline.clearCaches();</code>

官方url:

https://www.fresco-cn.org/docs/index.html

url1:http://blog.csdn.net/y1scp/article/details/49245535

url2:http://blog.csdn.net/hongensq/article/details/52623376

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 图片选择框架是一种方便开发者在应用中实现图片选择、展示和处理功能的工具。在Android开发过程中,经常需要处理用户选择的图片,比如上传图片、展示图片列表、编辑图片等等,而使用图片选择框架可以大大简化这些操作。 目前比较常用的Android图片选择框架有很多,其中一些比较知名的包括Glide、Picasso、Fresco等。这些框架提供了丰富的功能,可以轻松加载网络图片、本地图片、相册图片等,支持图片大小的处理、缓存、压缩以及图片展示等。 使用这些框架,我们可以通过简单的代码实现图片选择功能。通过调用框架提供的接口,我们可以从相册中选择一张或多张图片,获取图片的路径或URI,然后进行后续的处理,比如上传图片到服务器、展示图片列表、编辑图片等。 另外,这些框架还提供了图片加载的功能,可以帮助我们快速加载要展示的图片,并且支持图片的缓存和压缩。通过使用这些框架,我们可以有效地避免加载大量图片时出现的内存溢出等问题,并且提高图片加载的速度和性能。 总之,Android图片选择框架开发者提供了一种简单、高效的方式来处理图片选择和展示的需求,极大地简化了开发过程,同时也提高了用户体验。开发者可以根据具体的需求选择适合自己的图片选择框架,以提升应用的功能和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值