You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何捕获NetworkImage加载图片时的异常?

如何捕获NetworkImage加载图片时的异常?

问题背景

测试断网场景时,图片加载抛出如下异常:

解析图片编解码器时抛出以下HttpException:
Software caused connection abort, uri = https://firebasestorage.googleapis.com/v0/Cover%20Pictures%2F2022-08-22%2001%3A08%3A40.718456?alt=media&token=8b9c387e-c1fe-4cb7-843a-370d6cbfb43f

抛出异常时的堆栈信息:
Image provider: NetworkImage("https://firebasestorage.googleapis.com/v0/b...")

当前实现代码:

Container(
      decoration: BoxDecoration(
        color: Colors.grey,
        borderRadius: BorderRadius.all(Radius.circular(1.h)),
        image: DecorationImage(
          fit: BoxFit.cover,
          image: _coverImage != null
              ? FileImage(File(_coverImage!.path)) as ImageProvider
              : NetworkImage(authProvider.coverImageUrl!),
        ),
      ),
    ),

解决方案

方法1:改用Image组件的errorBuilder(推荐)

DecorationImage没有直接的错误回调,可通过Stack+Image组件模拟装饰图效果,利用errorBuilder捕获加载异常:

Stack(
  children: [
    Container(
      color: Colors.grey,
      borderRadius: BorderRadius.all(Radius.circular(1.h)),
    ),
    ClipRRect(
      borderRadius: BorderRadius.all(Radius.circular(1.h)),
      child: _coverImage != null
          ? Image.file(
              File(_coverImage!.path),
              fit: BoxFit.cover,
              width: double.infinity,
              height: double.infinity,
              errorBuilder: (context, error, stackTrace) {
                // 处理本地图片加载异常
                return Container(color: Colors.grey);
              },
            )
          : Image.network(
              authProvider.coverImageUrl!,
              fit: BoxFit.cover,
              width: double.infinity,
              height: double.infinity,
              errorBuilder: (context, error, stackTrace) {
                // 捕获NetworkImage加载异常(断网、链接失效等)
                print('图片加载失败: $error');
                return Container(color: Colors.grey); // 替换为自定义占位图或提示
              },
            ),
    ),
  ],
)

方法2:自定义ImageProvider适配DecorationImage

若必须使用DecorationImage,可封装一个带异常捕获的NetworkImage包装类:

class SafeNetworkImage extends ImageProvider<NetworkImage> {
  final String url;
  final Map<String, String>? headers;

  SafeNetworkImage(this.url, {this.headers});

  @override
  Future<NetworkImage> obtainKey(ImageConfiguration configuration) {
    return NetworkImage(url, headers: headers).obtainKey(configuration);
  }

  @override
  ImageStreamCompleter loadImage(NetworkImage key, ImageDecoderCallback decode) {
    return NetworkImage(key.url, headers: key.headers).loadImage(key, (bytes, encoding) {
      try {
        return decode(bytes, encoding);
      } catch (e) {
        // 捕获加载/解码异常
        print('图片加载异常: $e');
        // 返回默认占位图字节(示例为空白图,可替换为自定义占位图的字节数据)
        return decode(Uint8List.fromList([]), null);
      }
    });
  }
}

使用方式:

image: DecorationImage(
  fit: BoxFit.cover,
  image: _coverImage != null
      ? FileImage(File(_coverImage!.path)) as ImageProvider
      : SafeNetworkImage(authProvider.coverImageUrl!),
),

方法3:借助第三方包简化实现

使用cached_network_image包,它内置错误处理与缓存功能,可直接用于DecorationImage:

image: DecorationImage(
  fit: BoxFit.cover,
  image: _coverImage != null
      ? FileImage(File(_coverImage!.path)) as ImageProvider
      : CachedNetworkImageProvider(
          authProvider.coverImageUrl!,
          errorListener: (error) {
            print('图片加载失败: $error');
          },
        ),
),

内容的提问来源于stack exchange,提问作者Flutter Dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 10:48:16