欢迎光临
我们一直在努力

Fresco2.X 框架完整使用详解(Android Kotlin)

Fresco 是 Facebook 推出的Android 高性能图片加载框架,专为解决 Android 图片加载的痛点设计:自动处理内存 / 磁盘缓存、支持超大图渐进式加载、完美适配 RecyclerView 列表复用、自动释放内存(Activity 销毁时无需手动处理),还支持 GIF/WEBP 动图、图片裁剪 / 圆角等特效,是中大型 Android 项目的主流图片加载框架之一。

下面从依赖引入、基础配置、核心用法、高频场景、高级定制、避坑点全维度讲解,适配Gradle Kotlin DSL(build.gradle.kts) 和 Kotlin 语法,代码可直接复制使用,覆盖 99% 的开发场景。

一、核心优势(为什么选 Fresco)

对比 Glide/Picasso,Fresco 的核心优势集中在内存优化和大尺寸图片处理:

  • 内存占用极低:图片默认存储在Ashmem(匿名共享内存),而非 Java 堆,避免 OOM(内存溢出),尤其适合加载高清图 / 长图;
  • 自动缓存策略:三级缓存(内存 / 磁盘 / 网络),可自定义缓存规则,支持断点续传;
  • 动图原生支持:无需额外依赖,直接加载 GIF/WEBP 动图,支持暂停 / 播放;
  • 渐进式加载:超大图(如长图、高清海报)可像网页一样从模糊到清晰渐进加载,提升用户体验;
  • 生命周期绑定:与 Activity/Fragment 生命周期自动绑定,页面销毁时自动停止加载、释放资源,无需手动处理;
  • 丰富的图片特效:内置圆角、圆形、裁剪、淡入淡出等效果,无需自定义 ImageView。
  • 适用场景:需要加载高清图 / 长图、动图,或对内存优化要求高的项目(如电商、社交、资讯 APP);轻量场景:若仅加载普通小图,Glide 更轻量,可根据项目需求选择。

    二、前置步骤:依赖引入 + 权限配置(必做)

    2.1 添加 Fresco 核心依赖(app/build.gradle.kts)

    Fresco 的依赖支持按需引入(核心包 + 扩展包),基础使用仅需核心包,动图 / 网络扩展可按需添加。最新稳定版为 2.7.0,适配 Android 5.0+(API 21+),低版本需兼容配置(文末补充)。

    打开 App 模块的build.gradle.kts,在dependencies中添加依赖,同步后即可使用:

    kotlin

    dependencies {
    // 其他原有依赖(kotlin-stdlib、core-ktx等)保留
    implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.0")
    implementation("androidx.core:core-ktx:1.12.0")

    // 核心:Fresco基础包(必须加,支持本地/网络图片、缓存、基础特效)
    implementation("com.facebook.fresco:fresco:2.7.0")

    // 按需添加扩展包(根据业务需求选择,无需全部添加)
    implementation("com.facebook.fresco:animated-gif:2.7.0") // 支持GIF动图
    implementation("com.facebook.fresco:animated-webp:2.7.0") // 支持WEBP动图
    implementation("com.facebook.fresco:webpsupport:2.7.0") // 支持静态WEBP
    implementation("com.facebook.fresco:okhttp3-imagepipeline:2.7.0") // 用OkHttp3作为网络层(推荐,替代默认HttpURLConnection)
    }

    建议添加okhttp3-imagepipeline:Fresco 默认网络层是HttpURLConnection,替换为 OkHttp3 后支持HTTPS、拦截器、超时配置,更适配实际开发。

    2.2 配置网络权限(AndroidManifest.xml)

    加载网络图片 / 动图必须添加网络权限,Android 9.0+(API 28)若加载http链接图片,需开启明文网络支持:

    xml

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="你的项目包名">

    <!– 必加:网络权限(加载网络图片) –>
    <uses-permission android:name="android.permission.INTERNET" />
    <!– 可选:读写外部存储(加载本地图片/缓存到外部) –>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />

    <application
    android:name=".MyApp"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name">

    <!– Android 9.0+ 加载http链接图片需加:开启明文网络支持 –>
    <uses-library android:name="org.apache.http.legacy" android:required="false" />
    <meta-data
    android:name="android.webkit.WebSettings.ALLOW_UNIVERSAL_ACCESS_FROM_FILE_URLS"
    android:value="true" />
    <!– 或直接在res/xml创建network_security_config.xml,配置更灵活(推荐) –>

    <!– 你的Activity配置 –>
    <activity android:name=".MainActivity">
    <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    </activity>
    </application>
    </manifest>

    Android 10+ 存储适配:若需将缓存放在外部存储,需在application中添加android:preserveLegacyExternalStorage="true",或使用 Scoped Storage(作用域存储)。

    2.3 初始化 Fresco(全局唯一,Application 中执行)

    Fresco 必须全局初始化一次,建议放在自定义 Application 类的onCreate中,这是 Android 开发的最佳实践,避免多次初始化导致资源泄漏。

    步骤 1:创建自定义 Application 类

    kotlin

    import android.app.Application
    import com.facebook.drawee.backends.pipeline.Fresco

    class MyApp : Application() {
    override fun onCreate() {
    super.onCreate()
    // 基础初始化:默认配置(满足90%的基础场景)
    Fresco.initialize(this)

    // 进阶:自定义配置(如OkHttp3网络层、缓存大小、超时时间,文末高级部分讲解)
    // Fresco.initialize(this, getFrescoConfig())
    }
    }

    步骤 2:在 AndroidManifest.xml 中注册 Application

    xml

    <application
    android:name=".MyApp" <!– 对应自定义Application类 –>
    …>
    <!– 其他配置 –>
    </application>

    注意:初始化必须用Application 上下文,不能用 Activity 上下文,否则会导致内存泄漏。

    三、核心布局控件:SimpleDraweeView(替代 ImageView)

    Fresco不使用原生 ImageView,而是提供专属的SimpleDraweeView控件,所有图片加载 / 特效都通过该控件实现,它继承自ImageView,可直接在布局中使用,支持 XML 属性配置占位图、圆角、宽高比等。

    3.1 布局中使用 SimpleDraweeView(核心)

    在layout/xxx.xml中添加SimpleDraweeView,替代原有ImageView,基础属性说明:

    xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fresco="http://schemas.android.com/apk/res-auto" <!– 必加:Fresco命名空间 –>
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <!– 基础使用:加载网络图片,配置占位图、圆角 –>
    <com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/sdv_avatar"
    android:layout_width="100dp" <!– 支持固定宽高/match_parent/wrap_content –>
    android:layout_height="100dp"
    fresco:fadeDuration="300" <!– 淡入淡出动画时长(ms),默认300 –>
    fresco:placeholderImage="@mipmap/ic_placeholder" <!– 加载中占位图 –>
    fresco:placeholderImageScaleType="centerCrop" <!– 占位图缩放类型 –>
    fresco:errorImage="@mipmap/ic_error" <!– 加载失败占位图 –>
    fresco:retryImage="@mipmap/ic_retry" <!– 加载重试占位图 –>
    fresco:roundAsCircle="true" <!– 是否圆形显示(头像专用,与roundRadius二选一) –>
    <!– fresco:roundRadius="10dp" –> <!– 圆角半径(非圆形时使用) –>
    fresco:roundWithOverlayColor="@color/white" <!– 圆角边缘叠加色(解决透明图圆角锯齿) –>
    fresco:viewAspectRatio="1:1" <!– 宽高比(如16:9,设置后可省略width/height其中一个) –>
    />

    <!– 加载长图/超大图:支持渐进式加载 –>
    <com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/sdv_long_img"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    fresco:viewAspectRatio="3:4"
    fresco:placeholderImage="@mipmap/ic_placeholder"
    fresco:progressBarImage="@mipmap/ic_progress" <!– 进度条占位图(渐进式加载) –>
    fresco:progressBarImageScaleType="centerInside"
    />

    <!– 加载GIF动图:无需额外配置,核心包+animated-gif扩展即可 –>
    <com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/sdv_gif"
    android:layout_width="200dp"
    android:layout_height="200dp"
    fresco:placeholderImage="@mipmap/ic_placeholder"
    />

    </LinearLayout>

    核心 XML 属性说明(常用)

    属性名作用常用值
    fresco:placeholderImage 加载中占位图 本地 mipmap/drawable 资源
    fresco:errorImage 加载失败占位图 本地资源
    fresco:roundAsCircle 是否圆形显示 true/false(头像用)
    fresco:roundRadius 圆角半径 如10dp
    fresco:viewAspectRatio 宽高比 如16:9、1:1
    fresco:fadeDuration 淡入动画时长 如300(ms)
    fresco:progressBarImage 渐进式加载进度条 本地资源
    fresco:roundWithOverlayColor 圆角边缘色 如@color/white(解决透明图锯齿)

    注意:SimpleDraweeView的wrap_content需要配合viewAspectRatio使用,否则图片可能显示异常;固定宽高可直接使用,无需宽高比。

    四、核心用法:加载图片(Kotlin)

    Fresco 加载图片的核心是 **ImageRequest(图片请求)** + DraweeController(控制器),通过SimpleDraweeView.setController()绑定加载配置,支持网络图片、本地图片、Assets 图片、Drawable 图片等多种数据源,语法统一。

    先定义测试地址(方便复制测试)

    kotlin

    // 测试1:网络图片(jpg)
    val netImageUrl = "https://img1.baidu.com/it/u=123456,789012&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500"
    // 测试2:网络GIF动图
    val netGifUrl = "https://img1.baidu.com/it/u=345678,901234&fm=253&fmt=auto&app=138&f=GIF?w=300&h=300"
    // 测试3:本地图片(sdcard)
    val localImagePath = "file:///sdcard/Pictures/test.jpg"
    // 测试4:Assets图片(assets/test.png)
    val assetsImageUrl = "asset:///test.png"
    // 测试5:Drawable图片(R.drawable.test)
    val drawableResId = R.drawable.test

    4.1 基础加载:一行代码加载网络图片(默认配置)

    适合无需自定义配置的简单场景,用Fresco.newDraweeControllerBuilder()快速构建控制器:

    kotlin

    import android.os.Bundle
    import androidx.appcompat.app.AppCompatActivity
    import com.facebook.drawee.backends.pipeline.Fresco
    import com.facebook.drawee.view.SimpleDraweeView
    import com.facebook.imagepipeline.request.ImageRequest
    import com.facebook.imagepipeline.request.ImageRequestBuilder

    class MainActivity : AppCompatActivity() {
    private lateinit var sdvAvatar: SimpleDraweeView
    private lateinit var sdvGif: SimpleDraweeView
    private lateinit var sdvLongImg: SimpleDraweeView

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // 注意:Fresco初始化后,可直接设置布局,无需额外操作
    setContentView(R.layout.activity_main)

    // 绑定控件
    sdvAvatar = findViewById(R.id.sdv_avatar)
    sdvGif = findViewById(R.id.sdv_gif)
    sdvLongImg = findViewById(R.id.sdv_long_img)

    // 用法1:加载普通网络图片(基础版,一行代码)
    sdvAvatar.setImageURI(netImageUrl) // 极简用法,默认配置(推荐基础场景)

    // 用法2:加载GIF动图(无需额外配置,添加animated-gif扩展即可)
    sdvGif.setImageURI(netGifUrl)
    }
    }

    极简用法setImageURI(uri):底层自动构建默认的ImageRequest和DraweeController,满足 90% 的基础加载场景,推荐优先使用。

    4.2 进阶加载:自定义 ImageRequest(渐进式 / 超时 / 缓存)

    适合需要自定义加载规则的场景(如超大图渐进式加载、设置超时时间、禁用缓存、强制刷新),通过ImageRequestBuilder构建请求,灵活配置参数:

    kotlin

    // 用法3:加载超大图/长图 → 开启渐进式加载(核心)
    val longImageRequest = ImageRequestBuilder
    .newBuilderWithSource(Uri.parse(netImageUrl)) // 绑定图片地址(Uri格式)
    .setProgressiveRenderingEnabled(true) // 开启渐进式加载(从模糊到清晰)
    .setRequestPriority(ImageRequest.Priority.HIGH) // 设置加载优先级(HIGH/LOW/NORMAL)
    .setCacheChoice(ImageRequest.CacheChoice.DEFAULT) // 缓存策略(默认/仅内存/仅磁盘)
    .setNetworkFetchTimeout(5000) // 网络超时时间(ms),默认5000
    .build()

    // 构建DraweeController,绑定请求
    val longImgController = Fresco.newDraweeControllerBuilder()
    .setImageRequest(longImageRequest)
    .setAutoPlayAnimations(true) // 自动播放动图(默认true)
    .setOldController(sdvLongImg.controller) // 重用旧控制器(RecyclerView列表复用必备,防止闪烁)
    .build()

    // 绑定到控件
    sdvLongImg.controller = longImgController

    核心 ImageRequestBuilder 配置(常用)

    方法作用常用值
    setProgressiveRenderingEnabled(true) 开启渐进式加载 超大图 / 长图必开
    setRequestPriority(…) 加载优先级 HIGH(首屏图)/LOW(非首屏)
    setNetworkFetchTimeout(ms) 网络超时 如5000(ms)
    setCacheChoice(…) 缓存策略 DEFAULT(默认)/NO_CACHE(禁用缓存)
    setResizeOptions(ResizeOptions(w, h)) 图片缩放 如ResizeOptions(200,200)(像素),减少内存占用
    setLocalThumbnailPreviewsEnabled(true) 开启本地缩略图预览 加载本地大图时提速

    4.3 加载不同数据源(本地 / Assets/Drawable)

    Fresco 通过不同的 Uri 协议区分数据源,语法统一,仅需修改 Uri 格式,无需更改加载逻辑:

    kotlin

    import android.net.Uri
    import com.facebook.drawee.drawable.ScalingUtils

    // 1. 加载本地SDCard图片(协议:file:///)
    val localUri = Uri.parse("file:///sdcard/Pictures/test.jpg")
    sdvAvatar.setImageURI(localUri)

    // 2. 加载Assets目录图片(协议:asset:///,注意3个/)
    val assetsUri = Uri.parse("asset:///test.png") // 对应assets/test.png
    sdvAvatar.setImageURI(assetsUri)

    // 3. 加载Drawable/mipmap资源(需通过UriUtil构建)
    import com.facebook.common.util.UriUtil
    val drawableUri = Uri.parse(UriUtil.LOCAL_RESOURCE_SCHEME + ":" + R.drawable.test)
    sdvAvatar.setImageURI(drawableUri)

    // 4. 加载ContentProvider图片(如相册图片,协议:content://)
    val contentUri = Uri.parse("content://media/external/images/media/12345")
    sdvAvatar.setImageURI(contentUri)

    4.4 动图专属操作(暂停 / 播放 / 循环次数)

    加载 GIF/WEBP 动图后,可通过Animatable接口控制播放 / 暂停,支持设置循环次数:

    kotlin

    import com.facebook.drawee.controller.BaseControllerListener
    import com.facebook.imagepipeline.image.ImageInfo
    import com.facebook.drawee.controller.ControllerListener

    // 步骤1:构建控制器时,添加监听器(获取动图Animatable对象)
    val gifController = Fresco.newDraweeControllerBuilder()
    .setUri(netGifUrl)
    .setAutoPlayAnimations(false) // 关闭自动播放,手动控制
    .setControllerListener(object : BaseControllerListener<ImageInfo>() {
    // 图片加载完成回调
    override fun onFinalImageSet(
    id: String?,
    imageInfo: ImageInfo?,
    animatable: com.facebook.drawee.controller.Animatable?
    ) {
    super.onFinalImageSet(id, imageInfo, animatable)
    // 保存Animatable对象,用于手动控制
    animatable?.let {
    mGifAnimatable = it
    // 设置动图循环次数(-1为无限循环,默认)
    (it as? com.facebook.imagepipeline.animated.base.AnimatedDrawable)?.setLoopCount(3)
    }
    }
    })
    .build()

    sdvGif.controller = gifController

    // 步骤2:手动控制动图(按钮点击事件)
    private var mGifAnimatable: com.facebook.drawee.controller.Animatable? = null

    // 播放动图
    btnPlay.setOnClickListener { mGifAnimatable?.start() }
    // 暂停动图
    btnPause.setOnClickListener { mGifAnimatable?.stop() }

    五、高频场景:RecyclerView 列表图片加载(必懂)

    RecyclerView 列表中使用 Fresco 的核心是重用旧控制器,防止图片闪烁、重复加载,这是 Fresco 针对列表复用的专属优化,只需一行代码即可实现:

    kotlin

    import android.view.LayoutInflater
    import android.view.ViewGroup
    import androidx.recyclerview.widget.RecyclerView
    import com.facebook.drawee.view.SimpleDraweeView

    class ImageAdapter(private val imageList: List<String>) : RecyclerView.Adapter<ImageAdapter.ViewHolder>() {

    inner class ViewHolder(itemView: android.view.View) : RecyclerView.ViewHolder(itemView) {
    val sdvItem: SimpleDraweeView = itemView.findViewById(R.id.sdv_item)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    val view = LayoutInflater.from(parent.context).inflate(R.layout.item_image, parent, false)
    return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val imageUrl = imageList[position]
    // 核心:重用旧控制器(setOldController),防止列表滑动时图片闪烁/重复加载
    val controller = Fresco.newDraweeControllerBuilder()
    .setUri(imageUrl)
    .setOldController(holder.sdvItem.controller) // 关键代码,必须加
    .build()
    holder.sdvItem.controller = controller
    }

    override fun getItemCount() = imageList.size
    }

    核心原理:Fresco 会复用旧的加载控制器,避免列表项复用后重新发起网络请求,同时自动取消滑出屏幕的图片加载,节省流量和内存。

    六、高级定制:自定义 Fresco 配置(OkHttp3 / 缓存 / 超时)

    基础初始化Fresco.initialize(this)使用默认配置,实际开发中常需要替换网络层为 OkHttp3、自定义缓存大小、设置网络拦截器,通过ImagePipelineConfig构建自定义配置,步骤如下:

    6.1 自定义 OkHttp3 网络层(推荐)

    替换 Fresco 默认的HttpURLConnection为 OkHttp3,支持 HTTPS、拦截器(如添加请求头、日志拦截)、超时配置:

    kotlin

    import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory
    import com.facebook.imagepipeline.core.ImagePipelineConfig
    import okhttp3.OkHttpClient
    import java.util.concurrent.TimeUnit

    // 在自定义Application中构建自定义配置
    private fun getFrescoConfig(): ImagePipelineConfig {
    // 1. 构建OkHttpClient,自定义配置
    val okHttpClient = OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS) // 连接超时
    .readTimeout(10, TimeUnit.SECONDS) // 读取超时
    .writeTimeout(10, TimeUnit.SECONDS) // 写入超时
    .addInterceptor(MyLogInterceptor()) // 添加自定义日志拦截器
    .addInterceptor(MyHeaderInterceptor()) // 添加请求头拦截器(如Token)
    .build()

    // 2. 基于OkHttp3构建ImagePipelineConfig
    return OkHttpImagePipelineConfigFactory
    .newBuilder(this, okHttpClient)
    .setBitmapMemoryCacheParamsSupplier {
    // 3. 自定义内存缓存大小(可选)
    com.facebook.imagepipeline.cache.BitmapMemoryCacheParams(
    "myBitmapCache", // 缓存名称
    Int.MAX_VALUE, // 最大缓存条目
    100 * 1024 * 1024, // 最大缓存大小(100MB)
    Int.MAX_VALUE,
    Int.MAX_VALUE
    )
    }
    .setMainDiskCacheConfig(
    // 4. 自定义磁盘缓存配置(可选)
    com.facebook.imagepipeline.cache.DiskCacheConfig.newBuilder(this)
    .setBaseDirectoryPath(getExternalFilesDir("fresco_cache")) // 缓存路径
    .setBaseDirectoryName("image_cache")
    .setMaxCacheSize(500 * 1024 * 1024) // 磁盘最大缓存(500MB)
    .build()
    )
    .setDownsampleEnabled(true) // 开启图片降采样(自动缩放,减少内存)
    .build()
    }

    // 替换初始化代码
    Fresco.initialize(this, getFrescoConfig())

    6.2 常用高级配置说明

  • 内存缓存:默认按设备内存自动分配,自定义时建议设置为50-200MB;
  • 磁盘缓存:建议放在 App 私有目录(getExternalFilesDir),无需存储权限,App 卸载时自动删除;
  • 降采样(Downsample):开启后 Fresco 会根据SimpleDraweeView的尺寸自动缩放图片,避免加载原图导致内存浪费;
  • 拦截器:通过 OkHttp3 的拦截器可统一添加Token、User-Agent等请求头,或添加日志拦截器调试网络请求。
  • 七、Fresco 核心类关系(快速理解)

    为了避免混淆,简单梳理 Fresco 的核心类职责,帮助理解整体流程:

  • Fresco:全局入口类,负责初始化、获取全局配置;
  • SimpleDraweeView:图片展示控件,替代 ImageView,处理布局和特效;
  • ImageRequest:图片请求类,封装图片地址、加载规则、超时、缓存等配置;
  • DraweeController:加载控制器,绑定 ImageRequest 和 SimpleDraweeView,控制加载 / 暂停 / 复用;
  • ImagePipeline:核心加载引擎,处理三级缓存、网络请求、图片解码、内存管理;
  • Animatable:动图控制接口,实现 GIF/WEBP 的播放 / 暂停。
  • 核心流程:Fresco初始化 → 构建ImageRequest → 构建DraweeController绑定请求 → SimpleDraweeView设置控制器 → ImagePipeline处理加载 / 缓存 → 控件展示图片。

    八、Kotlin 专属避坑点(Fresco 2.7.0)

    Fresco 在 Android Kotlin 中使用的坑主要集中在控件使用、初始化、生命周期、内存优化,踩中后会出现图片不显示、OOM、内存泄漏等问题,务必注意:

    1. 禁止使用原生 ImageView 加载

    Fresco 的图片加载逻辑与SimpleDraweeView深度绑定,用 ImageView 无法加载,且会报空指针,必须使用com.facebook.drawee.view.SimpleDraweeView。

    2. 必须全局初始化一次,且用 Application 上下文

    • 初始化必须放在Application 的 onCreate中,不能在 Activity/Fragment 中初始化,否则会多次初始化导致资源冲突;
    • 初始化参数必须是Application 上下文(this),不能用 Activity 上下文,否则会导致 Activity 无法被 GC 回收,引发内存泄漏。

    3. RecyclerView 列表必须重用旧控制器

    列表中加载图片若未调用setOldController(holder.sdvItem.controller),会出现图片闪烁、重复加载、滑出屏幕后继续加载的问题,这是 Fresco 列表使用的核心禁忌。

    4. 避免设置 SimpleDraweeView 的 src 属性

    原生 ImageView 的setImageResource/setImageBitmap对SimpleDraweeView无效,且会覆盖 Fresco 的加载逻辑,必须用setImageURI()或setController()设置图片。

    5. 动图播放需注意内存释放

    GIF/WEBP 动图会占用较多内存,页面销毁时需手动暂停动图,避免内存泄漏:

    kotlin

    override fun onDestroy() {
    super.onDestroy()
    mGifAnimatable?.stop() // 暂停动图
    mGifAnimatable = null // 置空引用
    }

    6. Android 10+ 存储权限适配

    加载本地 SDCard 图片时,Android 10+(API 29)默认开启Scoped Storage,直接访问file:///sdcard会报权限错误,建议:

    • 加载相册图片使用ContentProvider(content://协议);
    • 自定义缓存路径使用 App 私有目录(getExternalFilesDir),无需存储权限。

    7. 混淆配置(Release 版必加)

    若项目 Release 版开启混淆(isMinifyEnabled = true),必须在proguard-rules.pro中添加 Fresco 的混淆规则,否则会出现类找不到、图片加载失败:

    proguard

    # Fresco 基础混淆规则
    -keep class com.facebook.** { *; }
    -keep interface com.facebook.** { *; }
    -keep enum com.facebook.** { *; }
    -keep class com.facebook.imagepipeline.** { *; }
    -keep class com.facebook.drawee.** { *; }
    -dontwarn com.facebook.**
    -dontwarn okio.**

    # 若使用OkHttp3网络层
    -keep class okhttp3.** { *; }
    -keep interface okhttp3.** { *; }
    -dontwarn okhttp3.**

    九、常见问题排查(图片不显示 / 加载失败)

    按步骤操作后若图片不显示,按以下顺序排查,99% 的问题都能解决:

  • 检查 Fresco 是否初始化:确认自定义 Application 已注册,且Fresco.initialize(this)已执行;
  • 检查网络权限:加载网络图片必须添加<uses-permission android:name="android.permission.INTERNET" />;
  • 检查 Uri 格式:不同数据源的 Uri 协议是否正确(如 Assets 是asset:///,3 个 /);
  • 检查依赖是否完整:加载动图需添加animated-gif/animated-webp扩展包;
  • 检查 SimpleDraweeView 属性:是否正确设置layout_width/layout_height,wrap_content是否配合viewAspectRatio;
  • 检查网络链接:是否是https链接(Android 9.0+ 默认禁止 http),或是否开启明文网络支持;
  • 检查日志:查看 Logcat 的Fresco/ImagePipeline相关日志,定位具体错误(如权限、网络超时、图片地址无效);
  • 清理缓存:Fresco 有默认缓存,可通过Fresco.getImagePipeline().clearCaches()清理缓存后重新测试;
  • 检查混淆规则:Release 版需添加 Fresco 的混淆规则,否则会解析失败。
  • 十、与 Glide 的对比(如何选择)

    Fresco 和 Glide 都是 Android 主流图片加载框架,各有优势,根据项目需求选择即可:

    特性FrescoGlide
    内存优化 极致(Ashmem 存储,非 Java 堆) 优秀(内存缓存,自动回收)
    大尺寸图片 支持渐进式加载,体验极佳 支持加载,但无原生渐进式
    动图支持 原生支持 GIF/WEBP,可手动控制 需添加glide-gif-drawable扩展
    控件依赖 必须使用 SimpleDraweeView 支持原生 ImageView,无控件依赖
    上手难度 稍高(配置多,控件专属) 极低(一行代码加载,API 简洁)
    体积 稍大(核心包≈2MB,全扩展≈5MB) 轻量(核心包≈1.5MB)
    生态 稳定,无频繁更新 活跃,持续更新,适配最新 Android 版本

    选择建议:

    • 选Fresco:项目需要加载高清图 / 长图、动图,或对内存优化要求极高(如电商、社交 APP);
    • 选Glide:轻量项目、快速开发,或习惯使用原生 ImageView,对大图片处理无特殊要求。

    十一、总结(核心关键点)

  • 核心步骤:添加依赖 → 配置权限 → Application 中初始化 Fresco → 布局使用 SimpleDraweeView → 代码中 setImageURI/setController 加载图片;
  • 核心控件:SimpleDraweeView是 Fresco 的核心,替代 ImageView,支持 XML 配置圆角 / 圆形 / 占位图;
  • 核心用法:极简加载用setImageURI(uri),自定义配置用ImageRequest+DraweeController;
  • 列表优化:RecyclerView 中必须调用setOldController()重用旧控制器,防止图片闪烁;
  • 高级定制:通过ImagePipelineConfig替换 OkHttp3 网络层、自定义缓存大小、添加拦截器;
  • 避坑核心:全局初始化一次、用 Application 上下文、不设置 src 属性、动图页面销毁时暂停;
  • 动图支持:添加animated-gif/animated-webp扩展包,通过Animatable接口控制播放 / 暂停。
  • 赞(0)
    未经允许不得转载:171主机测评 » Fresco2.X 框架完整使用详解(Android Kotlin)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址