Android Coil 3 ImageRequest.Builder error() 和 fallback()异同摘要在Coil3的ImageRequest.Builder中error()和fallback()都用于配置加载失败时的兜底图但触发条件不同。error()在data非空但加载失败如网络错误、文件不存在等时触发fallback()则在data为空时使用。两者通常与placeholder()配合使用placeholder()显示加载中fallback()处理无数据情况error()处理加载失败。建议同时配置两者以明确区分无数据和加载失败场景使语义更清晰。在 Coil 3 的ImageRequest.Builder里.error()和.fallback()都是用来配置“加载不出目标图片时显示什么”的但它们触发条件不同。一句话区分.error() data 非空但加载/获取/解码失败时使用 .fallback() data 为空/null 时使用1..error()是什么.error()表示请求失败时显示的兜底图。例如ImageRequest.Builder(context) .data(url) .error(R.drawable.ic_load_failed) .target(imageView) .build()当data本身不是null但是加载过程中失败比如网络请求失败 HTTP 404 文件不存在 Uri 打不开 权限不足 图片格式不支持 解码失败 图片损坏 Fetcher 抛异常 Decoder 抛异常这时 Coil 会显示.error()配置的 Drawable。2..fallback()是什么.fallback()表示请求的 data 为 null 时显示的兜底图。例如ImageRequest.Builder(context) .data(user.avatarUrl) // avatarUrl 可能为 null .fallback(R.drawable.ic_default_avatar) .target(imageView) .build()当user.avatarUrl nullCoil 不会真的去加载网络或本地图片而是认为这个请求没有有效数据源此时显示.fallback()配置的 Drawable。3. 核心差异对比项.error().fallback()触发条件data非空但加载失败data null代表含义有图片地址/资源但加载失败本来就没有图片数据常见原因网络失败、文件不存在、解码失败、权限失败用户头像为空、封面字段为空、业务没有配置图片是否表示异常通常是异常/失败通常是正常业务状态典型图片加载失败图、破图图标默认头像、默认封面、空状态图Listener 回调通常走onError通常也可能作为失败结果处理但 UI 使用 fallback4. 示例.error()适用场景场景 1图片 URL 有值但下载失败val request ImageRequest.Builder(context) .data(https://example.com/image.jpg) .placeholder(R.drawable.ic_loading) .error(R.drawable.ic_load_failed) .target(imageView) .build()如果 URL 404、网络超时、服务器异常会显示ic_load_failed场景 2本地 Uri 有值但文件不存在或无权限ImageRequest.Builder(context) .data(uri) .error(R.drawable.ic_broken_image) .target(imageView) .build()如果uri打不开或者图片损坏会显示.error()。5. 示例.fallback()适用场景场景 1用户没有头像ImageRequest.Builder(context) .data(user.avatarUrl) .fallback(R.drawable.ic_default_avatar) .error(R.drawable.ic_avatar_load_failed) .target(imageView) .build()如果user.avatarUrl null显示ic_default_avatar如果user.avatarUrl ! null但加载失败显示ic_avatar_load_failed场景 2列表封面字段为空ImageRequest.Builder(context) .data(item.coverUrl) .fallback(R.drawable.ic_default_cover) .error(R.drawable.ic_cover_error) .target(imageView) .build()含义是coverUrl null - 默认封面 coverUrl 有值但加载失败 - 加载失败图6. 如果只设置.error()没有设置.fallback()会怎样通常可以理解为data null 时如果没有 fallbackCoil 会退而使用 error例如ImageRequest.Builder(context) .data(null) .error(R.drawable.ic_error) .target(imageView) .build()此时大概率会显示ic_error也就是说.error()可以作为更通用的失败兜底图。但语义上如果你明确知道data可能为空最好还是单独配置.fallback()。7. 如果只设置.fallback()加载失败会怎样例如ImageRequest.Builder(context) .data(https://example.com/not-exist.jpg) .fallback(R.drawable.ic_default_avatar) .target(imageView) .build()如果data不为空但加载失败由于没有设置.error()那么 Coil 没有专门的 error 图可显示。结果可能是显示空 保持原图 target.onError(null)具体表现和 target / ImageView 状态有关。所以一般建议.fallback(...) .error(...)一起配置语义更清晰。8..placeholder()、.error()、.fallback()的关系这三个经常一起用ImageRequest.Builder(context) .data(url) .placeholder(R.drawable.ic_loading) .fallback(R.drawable.ic_default_avatar) .error(R.drawable.ic_load_failed) .target(imageView) .build()它们的触发阶段不同placeholder加载中显示 fallback data null 时显示 error data 非空但加载失败时显示流程大致是开始请求 ↓ 显示 placeholder ↓ 判断 data ↓ data null ? ├─ 是显示 fallback └─ 否继续 fetch/decode ↓ 成功显示 result.image 失败显示 error9. 在图/媒体场景里的理解假设加载本地媒体缩略图ImageRequest.Builder(context) .data(media.uri) .fallback(R.drawable.ic_no_media) .error(R.drawable.ic_media_broken) .target(imageView) .build()可以这样理解media.uri null说明业务层没有可加载的媒体地址。显示ic_no_media这是正常业务兜底。media.uri ! null但文件被删除比如数据库里还有记录但真实文件没了。显示ic_media_broken这是加载失败。media.uri ! null但权限丢失例如 Android 相册权限变化、SAF 授权失效。显示ic_media_broken这也是加载失败。10. 推荐用法如果业务上data可能为空建议这样写ImageRequest.Builder(context) .data(imageUrl) .placeholder(R.drawable.ic_loading) .fallback(R.drawable.ic_default_image) .error(R.drawable.ic_load_failed) .target(imageView) .build()语义清晰加载中 - placeholder 没有图片数据 - fallback 有数据但加载失败 - error 加载成功 - result.image11. 总结.error()和.fallback()都是兜底图但含义不同.error()用于有 data但是加载失败例如网络错误、文件不存在、解码失败。.fallback()用于data null例如用户没有头像、业务没有封面、媒体 Uri 为空。推荐理解fallback 是“无数据兜底” error 是“失败兜底”