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
相关产品推荐
相关产品推荐

