Fresco入门使用及简单特性介绍

概述

屏幕快照 2019-06-30 17.00.20

随着摄影技术的不断发展和普及,我们的应用程序大多数都具有显示图片这样的需求,在Android移动设备上,由于平台计算能力的差异、设备硬件的差异,我们很难将图片在不同的设备上完美地显示,经常出现的情况是一份展示图片的代码在高性能手机上运行很流畅,但是部署到硬件稍微差劲一点的设备上就会出现卡顿、占用内存比例过大、甚至应用崩溃的现象。所以我们最好能寻求一种框架,可以帮我们处理不同计算能力平台上的差异性,对图片的显示进行内存等方面的优化,使我们的应用可以在不同的设备上完美地显示图片,Fresco就是这样一个强大的图片加载组件,它是Facebook开发及开源的一个框架,通过Fresco,你不需要关心图片的加载和显示这些琐碎的事情,只需要告诉它要以何种方式显示图片即可,剩下的事情都交给它,真正体现了代码重用、避免重复造轮子的原则。

本文将带大家逐步入门Fresco的使用和基本特性,带大家体会使用Fresco的优点,本文不涉及过多Fresco源码部分及底层原理部分的内容,宗旨是先带大家入门,后面我会陆续推出关于Frecsco源码分析的文章,力争带大家深入Fresco的底层原理。

Fresco初步尝鲜

本节带大家一步一步通过Fresco显示一张网络图片,最终效果是这样的:

image-20190630220713863

即在我们的手机上通过Fresco显示一张小熊熊的照片。

引入Fresco

Fresco官方github地址:https://github.com/facebook/fresco

使用所有开源库的第一步一定是引入相关依赖,将下面这行代码加入到Android项目的build.gradle(app)文件中即可:

implementation 'com.facebook.fresco:fresco:2.0.0'

上面的是Fresco的基本依赖,Fresco还提供了其他的一些高级功能,比如展示Gif之类的,为了控制库的大小,Fresco将这些子功能分开到其他子库中,大家按需添加即可:

dependencies {
  // 在 API < 14 上的机器支持 WebP 时,需要添加
  compile 'com.facebook.fresco:animated-base-support:2.0.0'

  // 如果要显示 GIF 动图,需要添加
  compile 'com.facebook.fresco:animated-gif:2.0.0'

  // 支持显示 WebP (静态图+动图)
  compile 'com.facebook.fresco:animated-webp:2.0.0'
  compile 'com.facebook.fresco:webpsupport:2.0.0'

  // 仅支持显示 WebP 静态图
  compile 'com.facebook.fresco:webpsupport:2.0.0'
}
使用Fresco

在使用Fresco之前,我们需要在我们的应用中初始化Fresco,初始化的代码为:

Fresco.initialize(this);

那么这行代码应该写在我们应用的什么位置?Fresco官方的说法是,Fresco的初始化工作在整个应用的生命周期只需要初始化一次,多次初始化没有任何意义,联想一下,什么地方的代码在整个应用的生命周期只会执行一次?答案是应用ApplicationonCreate()方法啊,所以我们新建一个Application并初始化Fresco

package edu.nuaa.aiexception.learnopensource;

import android.app.Application;

import com.facebook.drawee.backends.pipeline.Fresco;

/**
 * @author dmrfcoder
 * @date 2019-06-30
 */

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Fresco.initialize(this);
    }
}

不要忘记在项目的Manifest文件中指定Application

 <application
        android:name=".MyApplication"
        ...
 />

至此,Fresco已经初始化好了。

我们需要从网络加载图片,所以必须要在Manifest文件中为应用加上网络请求的权限:

 <uses-permission android:name="android.permission.INTERNET"/>

然后我们需要在界面上放置一个Fresco的控件,因为我们仅仅是想简单下载一张网络图片,在下载完成之前,显示一张占位图,可以使用最简单的 SimpleDraweeView

 <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/fresco_view"
        android:layout_width="130dp"
        android:layout_height="130dp"
        android:layout_centerHorizontal="true"
        app:placeholderImage="@mipmap/ic_launcher" />

然后我们就可以在Java代码中为SimpleDraweeView设置图像了:

public void loadPicFromNet() {
        Uri uri = Uri.parse("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2133031131,1997928181&fm=26&gp=0.jpg");
    imageView.setImageURI(uri);
}

然后直接运行代码,这里笔者运行的时候遇到了如下报错:

java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/core/util/Pools$SynchronizedPool;

解决方案是在你项目的gradle.properties文件中加入如下两行即可:

android.enableJetifier = true
android.useAndroidX=true

希望可以帮大家避坑。

然后运行代码,最终效果如下:

屏幕录制 2019-06-30 22.09.08

可以看到,在图片从网络上下载下来之前,会展示我们设置的占位图,当图片下载完成之后,Fresco才会将下载下来的图片显示到屏幕上,这样用户体验会更好。

总结一下,在上例中,Fresco替我们完成的事情有:

剩下的,Fresco会替你完成:

  • 显示占位图直到加载完成;
  • 下载图片;
  • 缓存图片;
  • 图片不再显示时,从内存中移除

可以看到,通过Fresco的使用,我们不再需要关心图片的下载、缓存、清除等一系列事件,只需要关注图片的显示即可,将我们的意图描述给Fresco,剩下的事情都由它来完成,是不是很方便啊~

Fresco中的几个关键概念

Drawees

Drawees的作用是在图片加载完成前显示占位图,加载成功后自动替换为目标图片。当图片不再显示在屏幕上时,它会及时地释放内存和空间占用

Drawees由三个元素组成,有点像MVC模式,分别是:

DraweeView

继承于 View, 负责图片的显示。

一般情况下,使用 SimpleDraweeView 即可。 你可以在 XML 或者在 Java 代码中使用它,通过 setImageUri 给它设置一个 URI 来使用,上面的实例就是借助SimpleDraweeView来实现的网络图片显示。

我们可以设置DraweeViewXML属性来达到各式各样的效果,这一点我会在下面详细讲解。

DraweeHierarchy

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

你可以通过它来在Java代码中自定义图片的展示。

DraweeController

DraweeController 负责和 image loader 交互( Fresco 中默认为 image pipeline, 当然你也可以指定别的),可以创建一个这个类的实例,来实现对所要显示的图片做更多的控制。

如果你还需要对Uri加载到的图片做一些额外的处理,那么你会需要这个类的。

DraweeControllerBuilder

DraweeControllersDraweeControllerBuilder 采用 Builder 模式创建,创建之后,不可修改。

Listeners

使用 ControllerListener 的一个场景就是设置一个Listener监听图片的下载。

The Image Pipeline

FrescoImage Pipeline 负责图片的获取和管理。图片可以来自远程服务器,本地文件,或者Content Provider,本地资源。压缩后的文件缓存在本地存储中,Bitmap数据缓存在内存中。

在5.0系统以下,Image Pipeline 使用 pinned purgeablesBitmap数据避开Java堆内存,存在ashmem中。这要求图片不使用时,要显式地释放内存。

SimpleDraweeView自动处理了这个释放过程,所以没有特殊情况,尽量使用SimpleDraweeView,在特殊的场合,如果有需要,也可以直接控制Image Pipeline

Fresco都支持哪些类型的URL?

Fresco 支持许多URI格式。

特别注意:Fresco 不支持 相对路径的URI. 所有的 URI 都必须是绝对路径,并且带上该 URIscheme

如下:

类型SCHEME示例
远程图片http://, https://HttpURLConnection
本地文件file://FileInputStream
Content providercontent://ContentResolver
asset目录下的资源asset://AssetManager
res目录下的资源res://Resources.openRawResource
Uri中指定图片数据data:mime/type;base64,数据类型必须符合rfc2397规定(仅支持 UTF-8)

res 示例:

Uri uri = Uri.parse("res://包名(实际可以是任何字符串甚至留空)/" + R.drawable.ic_launcher); 

注意,只有图片资源才能使用在Image pipeline中,比如(PNG)。其他资源类型,比如字符串,或者XML DrawableImage pipeline中没有意义。所以加载的资源不支持这些类型。

ShapeDrawable这样声明在XML中的drawable可能引起困惑。注意到这毕竟不是图片。如果想把这样的drawable作为图像显示,那么把这个drawable设置为占位图,然后把URI设置为null

总结

本文我们通过一个实例带大家过了一遍Fresco的基本使用流程,并且对Fresco中的基本概念做了简单介绍,由于Fresco DraweeFresco Image PipelineFresco比较重要,且知识点比较繁杂,我会在最近分别就DraweeImage PipelineFresco做详细介绍,届时将向大家展示一些Fresco的高级用法,欢迎大家关注。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值