Flutter中Image.network导航后抛404异常,errorBuilder无效
解决Flutter Image.network配置errorBuilder仍抛出NetworkImageLoadException的问题
问题原因
errorBuilder仅负责在UI层面展示加载失败的替代组件,无法阻止Flutter的图片资源服务在后台加载图片失败时输出异常日志。当导航到其他页面后,图片资源可能因缓存回收、资源释放等原因被触发重新请求,此时404错误会被框架捕获并打印,即使errorBuilder已经正常工作。
解决方案
方法一:自定义静默加载的NetworkImage
重写NetworkImage的加载方法,捕获加载异常并处理,避免异常向上抛出:
import 'dart:typed_data'; import 'package:flutter/painting.dart'; class SilentNetworkImage extends NetworkImage { const SilentNetworkImage( String url, { double scale = 1.0, Map<String, String>? headers, }) : super(url, scale: scale, headers: headers); @override Future<Codec> _loadAsync( String url, StreamController<ImageChunkEvent> chunkEvents, ImageDecoderCallback decode, Map<String, String>? headers, ) async { try { return await super._loadAsync(url, chunkEvents, decode, headers); } on NetworkImageLoadException catch (_) { // 返回空字节流生成的Codec,配合errorBuilder展示错误UI final bytes = Uint8List(0); return decode(await ImmutableBuffer.fromUint8List(bytes)); } } }
使用示例:
SizedBox( height: 100, width: 100, child: Image( image: const SilentNetworkImage('https://logo.clearbit.com/tmall.com'), errorBuilder: (context, error, stackTrace) { return const Center(child: Text('Something wrong!')); }, ), )
方法二:用FutureBuilder手动控制图片加载流程
手动发起网络请求并捕获异常,完全掌控加载状态和错误处理:
import 'package:http/http.dart' as http; import 'dart:typed_data'; // ... SizedBox( height: 100, width: 100, child: FutureBuilder<Uint8List?>( future: _fetchImageBytes('https://logo.clearbit.com/tmall.com'), builder: (context, snapshot) { switch (snapshot.connectionState) { case ConnectionState.waiting: return const CircularProgressIndicator(); // 加载中 case ConnectionState.done: if (snapshot.hasData) { return Image.memory(snapshot.data!); } else { return const Center(child: Text('Something wrong!')); } default: return const Center(child: Text('Something wrong!')); } }, ), ) // 图片加载方法 Future<Uint8List?> _fetchImageBytes(String url) async { try { final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { return response.bodyBytes; } return null; } catch (_) { return null; } }
注意:使用此方法需要在pubspec.yaml中添加http依赖:
dependencies: http: ^1.1.0
针对cached_network_image的适配
如果使用cached_network_image,可以参考方法一的思路,自定义CacheManager或者通过imageBuilder结合手动加载逻辑,避免异常日志输出。
内容的提问来源于stack exchange,提问作者Kvu
相关产品推荐
相关产品推荐

