ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Coil 3 ImageRequest 完全指南:构建、执行与配置图片加载请求

Coil 3 ImageRequest 完全指南:构建、执行与配置图片加载请求 Coil 3 ImageRequest 完全指南构建、执行与配置图片加载请求【免费下载链接】coilImage loading for Android and Compose Multiplatform.项目地址: https://gitcode.com/gh_mirrors/co/coilImageRequest是 Coil 3 中描述如何加载一张图片的不可变值对象value object它承载了从数据源、目标控件到缓存策略、变换效果在内的全部加载信息。本文以 docs/image_requests.md 为主线结合 coil-core 源码 深入讲解ImageRequest的构建、执行、平台扩展与核心配置项帮助你在 Android 与 Compose Multiplatform 场景下写出准确、可维护的图片加载代码。一、ImageRequest一个描述加载意图的值对象ImageRequest是 Coil 3 的核心抽象之一。它的职责非常单一收集并封装一次图片加载所需的全部信息然后交给ImageLoader去执行。它本身不执行任何网络请求、解码或缓存逻辑——那些都属于ImageLoader的职责范围。从源码看ImageRequest是一个不可变immutable的类字段在构造时一次确定之后不可修改Poko class ImageRequest private constructor( val context: PlatformContext, val data: Any, val target: Target?, val listener: Listener?, val memoryCacheKey: String?, val diskCacheKey: String?, ... )这里有两个值得注意的细节构造函数是private的你不能直接ImageRequest(...)来创建实例必须通过Builder。这保证了请求在构建过程中的中间状态不会泄漏到外部构建完成后的对象一定是完整、一致的。Poko注解这是 Coil 自带的注解自动为类生成基于所有字段的equals、hashCode和toString实现源码见 coil-core/src/commonMain/kotlin/coil3/annotation。这使得ImageRequest可以作为纯值参与比较、缓存键计算等操作。在 ImageRequest.kt 的 KDoc 中明确写道它对应ImageLoader.enqueue和ImageLoader.execute两种使用方式——这一点我们会在后面详细展开。二、使用 Builder 构建一个请求创建ImageRequest的唯一入口是ImageRequest.Builder它接收一个PlatformContext在 Android 上通常是Contextval request ImageRequest.Builder(context) .data(https://example.com/image.jpg) .crossfade(true) .target(imageView) .build()这段示例涵盖了三个最常用的配置.data(...)设置要加载的数据源可以是 URL 字符串、File、Uri、资源 ID 等任意类型.crossfade(true)请求成功时启用交叉淡入淡出动画.target(imageView)把加载结果交给ImageView显示。构建完成后把请求交给ImageLoader执行即可imageLoader.enqueue(request)2.1 Builder 的默认值体系Builder并不是把所有字段都置空而是采用默认值 显式覆盖的设计。在 ImageRequest.kt 的Defaults类中可以看到所有未设置项使用的默认值配置项默认值说明fileSystemdefaultFileSystem()磁盘读写所用的文件系统interceptorCoroutineContextEmptyCoroutineContext拦截器链执行上下文fetcherCoroutineContextioCoroutineDispatcher()Fetcher 抓取数据的协程上下文decoderCoroutineContextioCoroutineDispatcher()Decoder 解码的协程上下文memoryCachePolicyCachePolicy.ENABLED内存缓存读写策略diskCachePolicyCachePolicy.ENABLED磁盘缓存读写策略networkCachePolicyCachePolicy.ENABLED网络缓存读写策略placeholderFactory空工厂不显示占位图请求开始时的占位图errorFactory空工厂不显示错误图请求失败时的错误图fallbackFactory空工厂不显示兜底图data 为 null 时的兜底图sizeResolverSizeResolver.ORIGINAL目标尺寸解析器scaleScale.FIT缩放算法precisionPrecision.EXACT尺寸精度extrasExtras.EMPTY附加扩展属性build()方法在组装最终对象时会执行value ?: defaults.value的合并逻辑见 build() 实现凡是 Builder 上没有显式设置的字段一律回落到Defaults中的默认值。这意味着你可以只关心需要定制的少量配置其余行为由 Coil 的默认值保证。2.2 全局默认值与 per-request 覆盖这些默认值既可以由ImageLoader.Builder在全局层面设置例如imageLoaderBuilder.defaults(...)或单独调用.precision()、.crossfade()、.placeholder()等见 ImageLoader.kt 的 Builder也可以在单个请求上用ImageRequest.Builder.defaults(defaults)覆盖。ImageLoader上设置的默认值会随请求一起生效实现全局统一、局部微调的配置策略。另外每个ImageRequest还保存了一份Defaults引用以及一份Defined记录——Defined精确追踪哪些字段是被显式设置的见 Defined 类这是某个值到底是指定的还是走默认这一语义的可靠依据。2.3 基于已有请求创建新请求ImageRequest还提供了newBuilder()方法可以从已有请求复制出新的 Builder 再修改适合同一张图换尺寸/换目标重发的场景val request ImageRequest.Builder(context) .data(https://example.com/image.jpg) .build() val retry request.newBuilder() .size(512, 512) .build()newBuilder()的默认参数是原请求的context实现见 ImageRequest.kt内部委托给Builder(request, context)构造器它会复制原请求的全部字段见 Builder(request) 构造器。三、将请求交给 ImageLoaderenqueue 与 execute构建完ImageRequest后ImageLoader提供两种执行方式接口定义见 ImageLoader.kt3.1 enqueue异步入队fun enqueue(request: ImageRequest): Disposableenqueue把请求放入队列异步执行立即返回一个Disposable见 Disposable.ktjob: DeferredImageResult请求对应的协程任务isDisposed判断请求是否已完成或正在取消dispose()取消请求并释放资源。对于绑定到 View 的请求通常配合生命周期管理调用dispose()防止泄漏而在 Compose 中enqueue一般由AsyncImage等组件在内部代为管理。3.2 execute挂起式执行suspend fun execute(request: ImageRequest): ImageResultexecute在调用方的协程作用域内同步等待结果适合在业务逻辑中主动取回图片。它返回ImageResult这是一个密封接口sealed interface只有两种实现见 ImageResult.ktSuccessResult加载成功携带image、dataSource图片来源MEMORY/DISK/NETWORK等、memoryCacheKey、diskCacheKey、isSampled是否被降采样等元信息ErrorResult加载失败携带throwable异常对象。val result imageLoader.execute(request) when (result) { is SuccessResult - handleImage(result.image) is ErrorResult - handleError(result.throwable) }3.3 data 为 null 时的语义如果data传了nullbuild()会把数据替换为NullRequestData见 build()。这类请求最终会走fallback兜底图逻辑若未设置 fallback则抛出 NullRequestDataException。因此对可能为空的 URL场景设置 fallback 是一种稳健做法。四、平台特定扩展函数与导入规则Coil 3 是一个 Kotlin Multiplatform 项目其 API 分为公共 API与平台特定 API两部分。官方文档特别强调了一个重要的导入规则在 Coil 3.x 中ImageRequest的平台特定函数例如ImageRequest.Builder.target(ImageView)以扩展函数形式实现需要单独导入。具体来说ImageRequest.Builder.target(ImageView)定义在 coil-core/src/androidMain/kotlin/coil3/request/imageRequests.android.kt是一个典型的 Android 平台扩展函数在 Kotlin/NativeiOS 等或 JVM 平台对应实现位于各自的平台源码集中如 appleMain 下的imageRequests.apple.kt等。因此Android 代码中如果直接调用.target(imageView)需要显式 importimport coil3.request.target // 平台扩展函数需要单独导入crossfade同样是扩展函数体系公共源码 imageRequests.kt 中声明了expect fun ImageRequest.Builder.crossfade(durationMillis: Int)各平台提供actual实现。crossfade(true)的便捷重载会把动画时长设置为DEFAULT_CROSSFADE_MILLIS 200毫秒即fun ImageRequest.Builder.crossfade(enable: Boolean) crossfade(if (enable) DEFAULT_CROSSFADE_MILLIS else 0)如果你希望自定义时长直接调用crossfade(300)这样的整数重载即可。五、核心配置项详解ImageRequest.Builder提供了覆盖加载全链路的配置方法下面按用途分组说明方法签名均出自 ImageRequest.kt。5.1 数据源与目标方法说明data(Any?)设置数据源。Coil 会通过注册的 Fetcher 把任意类型转换为输入流URL 字符串、File、Uri、ByteArray 等都支持target(Target?)设置回调目标。Target接口包含onStart、onError、onSuccess三个回调见 Target.kt也有便捷的 lambda 重载target(onStart, onError, onSuccess)用 lambda 直接创建匿名Target免去实现接口的样板代码5.2 尺寸、缩放与精度方法说明size(Int)/size(Int, Int)/size(Dimension, Dimension)/size(Size)设置期望的目标宽高单位 pxsize(SizeResolver)自定义尺寸解析器例如根据 View 尺寸或特定策略动态解析scale(Scale)缩放算法FIT等比缩放适配或FILL填满裁剪对应枚举定义见 Scale.ktprecision(Precision)尺寸精度EXACT必须精确匹配、INEXACT允许近似、AUTOMATIC自动权衡通常为尺寸的 1/2 或 1/4枚举定义见 Precision.ktsize相关的数据类型Size、Dimension、SizeResolver都位于 coil-core/src/commonMain/kotlin/coil3/size 目录下。注意precision的 KDoc 提示当size为Size.ORIGINAL时返回图片尺寸总是等于或大于原图尺寸见 precision 的注释。5.3 占位图、错误图与兜底图方法说明placeholder(Image?)/placeholder((ImageRequest) - Image?)请求开始、尚未加载完成时显示的占位图支持直接传图或传工厂函数error(Image?)/error((ImageRequest) - Image?)请求失败时显示的错误图fallback(Image?)/fallback((ImageRequest) - Image?)data为 null 时显示的兜底图placeholderMemoryCacheKey(String?)/placeholderMemoryCacheKey(MemoryCache.Key?)指定内存缓存键若该键对应缓存命中则直接用缓存图作为占位图否则回落到placeholder见 placeholderMemoryCacheKey 实现占位/错误/兜底图都同时提供直接给图和给工厂两种形式。工厂形式接收ImageRequest参数可以在运行时根据请求内容动态决定显示哪张图灵活性更高。它们最终都会以placeholderFactory、errorFactory、fallbackFactory的形式存入请求并在 ImageRequest 的placeholder()/error()/fallback()方法中按请求级工厂 → 默认工厂的顺序取值。5.4 缓存策略Coil 3 用CachePolicy枚举统一描述三级缓存的读写策略定义见 CachePolicy.ktenum class CachePolicy(val readEnabled: Boolean, val writeEnabled: Boolean) { ENABLED(true, true), // 可读可写 READ_ONLY(true, false), // 只读不写 WRITE_ONLY(false, true), // 只写不读 DISABLED(false, false), // 完全禁用 }对应三个 Builder 方法方法作用对象说明memoryCachePolicy(CachePolicy)内存缓存控制是否从内存缓存读图、是否写入内存缓存diskCachePolicy(CachePolicy)磁盘缓存控制磁盘缓存的读写networkCachePolicy(CachePolicy)网络层只控制读取KDoc 明确注明禁用写入无效见 networkCachePolicy常见用法例如不想让某张敏感图片进入磁盘缓存可设置diskCachePolicy(CachePolicy.WRITE_ONLY)或CachePolicy.DISABLED希望强制刷新网络图片时可设置memoryCachePolicy(CachePolicy.WRITE_ONLY).diskCachePolicy(CachePolicy.WRITE_ONLY)跳过读缓存。5.5 缓存键方法说明memoryCacheKey(String?)/memoryCacheKey(MemoryCache.Key?)自定义内存缓存键不设置时由ImageLoader根据 data 自动计算见 memoryCacheKey KDocmemoryCacheKeyExtra(key, value)/memoryCacheKeyExtras(Map)向内存缓存键追加额外信息用于区分数据相同但渲染效果不同的请求diskCacheKey(String?)自定义磁盘缓存键同样默认自动计算一个典型场景是配合变换使用.transformations(...)扩展函数在内部就会把变换列表追加为memoryCacheKeyExtra(coil#transformations, ...)见 transformations 实现确保同一张原图经过不同变换不会错误地共享缓存。5.6 监听回调listener(...)提供 lambda 形式的便捷重载四个回调分别对应加载生命周期见 Listener 接口ImageRequest.Builder(context) .data(url) .listener( onStart { request - /* 请求开始 */ }, onCancel { request - /* 请求被取消 */ }, onError { request, result - /* 加载失败 */ }, onSuccess { request, result - /* 加载成功 */ }, ) .build()Listener与Target的区别在于Target负责把图交给谁显示Listener负责观察请求生命周期事件两者可以同时使用。5.7 协程上下文方法说明coroutineContext(CoroutineContext)一次设置拦截器、Fetcher、Decoder 三段执行上下文见 coroutineContextinterceptorCoroutineContext(...)拦截器链的执行上下文fetcherCoroutineContext(...)Fetcher.fetch()的执行上下文默认 IO 调度器decoderCoroutineContext(...)Decoder.decode()的执行上下文默认 IO 调度器默认情况下 Fetcher 与 Decoder 在 IO 线程执行、拦截器链在调用者上下文执行这些默认值同样定义在Defaults中ioCoroutineDispatcher()需要特殊调度策略时再显式覆盖。5.8 高级扩展选项除了 Builder 内建方法Coil 还通过 imageRequests.kt 中的扩展函数提供了一批附加选项它们基于Extras机制实现同时以ImageRequest.Builder、ImageLoader.Builder两个入口暴露扩展函数默认值说明transformations(vararg/list)空列表设置输出图片的变换链如圆角、模糊等并自动参与内存缓存键计算maxBitmapSize(Size)Size(4096, 4096)限制位图最大宽高Fetcher/Decoder 应遵守该约束避免超大内存分配传Dimension.Undefined可放开限制见 maxBitmapSizeaddLastModifiedToFileCacheKey(Boolean)false加载本地文件时把文件最后修改时间纳入内存缓存键文件更新后能自动触发重新加载见 addLastModifiedToFileCacheKeyallowConversionToBitmap(Boolean)true允许把非位图结果转换为位图以应用变换设为false时非位图结果将跳过变换见 allowConversionToBitmap六、与 ImageLoader 的关系ImageRequest和ImageLoader是 Coil 3 的两个互补抽象ImageRequest描述做什么它是一个纯值对象可自由创建、复用、比较ImageLoader负责怎么做它是一个服务类管理缓存、网络抓取、解码、请求调度与内存官方建议在整个应用中创建单个实例并共享见 ImageLoader 的 KDoc。请求通过enqueue或execute进入ImageLoader后会依次经过拦截器链、Fetcher抓取数据、Decoder解码、变换与缓存写入等阶段完整链路可参考 docs/image_pipeline.md 与 docs/image_loaders.md。ImageLoader默认会构建内存缓存按应用可用内存百分比见 ImageLoader.Builder.build()与全局共享的磁盘缓存因此绝大多数场景下你只需要构造ImageRequest把缓存细节交给默认实现。七、最佳实践小结请求级配置优先全局默认值兜底把通用的crossfade、占位图、缓存策略放到ImageLoader.Builder上统一设置仅在单个请求上覆盖差异项避免每个请求重复冗长配置。记得导入平台扩展函数使用target(ImageView)、crossfade(...)等平台特定扩展时显式import coil3.request.target这是 Coil 3 多平台架构下的必要步骤。善用newBuilder()复用请求需要基于同一数据源发起不同尺寸/目标的新请求时用request.newBuilder()派生避免重复设置 data。用Listener观察、用Target渲染两个回调体系职责不同按需选择或组合。设置 fallback 兜底对可能为 null 的数据源设置fallback避免触发NullRequestDataException。敏感图片管控缓存使用diskCachePolicy/memoryCachePolicy控制敏感内容不落缓存。相关 API 的完整签名与更细粒度说明可查阅 Coil 3 的 API 文档coil3.request.ImageRequest见 coil-core API 目录以及仓库中的测试与示例如 RealImageLoaderTest.kt、RealImageLoaderAndroidTest.kt它们展示了ImageRequest在实际加载流程中的完整行为。【免费下载链接】coilImage loading for Android and Compose Multiplatform.项目地址: https://gitcode.com/gh_mirrors/co/coil创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表