try/catch 在网络图像上不起作用(例外:图像数据无效)

Posted

技术标签:

【中文标题】try/catch 在网络图像上不起作用(例外:图像数据无效)【英文标题】:try/catch not working on network image (Exception: Invalid image data) 【发布时间】:2021-04-14 18:33:45 【问题描述】:

我已经获得了网络图像并使用了三元运算符,我可以在其中显示网络图像但无法显示默认资产图像,其中网络图像无效default image in grid 也是这样-

我是 Flutter 新手

 image: NetworkImage(products[index]
                                              .productImageList[0]
                                  )!= null
                                      ? NetworkImage(
                                      products[index].productImageList[0])
                                      :Image.asset("assets/defimg.jpg"),
                                  fit: BoxFit.fitHeight ),

它在索引 0 上显示网络图像,但不加载网络图像无效或为空的资产图像并抛出此错误-

════════ Exception caught by image resource service ════════════════════════════════════════════════
The following _Exception was thrown resolving an image codec:
Exception: Invalid image data

When the exception was thrown, this was the stack: 
#0      _futurize (dart:ui/painting.dart:5230:5)
#1      ImageDescriptor.encoded (dart:ui/painting.dart:5098:12)
#2      instantiateImageCodec (dart:ui/painting.dart:1998:60)
<asynchronous suspension>

在此之后我尝试了 try/catch - 我的带有 try catch 的代码是 --

child: Builder(builder: (BuildContext context) 
                              try 
                                return Center(
                                  child: Image.network(
                                      products[index]
                                                .productImageList[0],
                                      fit: BoxFit.contain,
                                  ),
                                );
                               catch (e) 
                                print("Got exception $e.toString()");
                                return Image.asset("assets/defimg.jpg", fit: BoxFit.contain);
                              
                            ),

给我和上面一样的错误..

图像响应来自列表“productImageList”中的 api,如下所示 --

            "sellingPrice": "4000",
            "productImageList": [
                "https://www.xyzz.com/postadsimages/img/23682201.jpg"
            ],
            "createdDate": 1607754473000,

【问题讨论】:

【参考方案1】:

Image.network 允许您处理网络请求的加载和错误状态,但不是您尝试的方式。

我会给你一个应该怎么做的例子:

// Just to DRY
final Image noImage = Image.asset("assets/defimg.jpg");
final imageUrl = products[index].productImageList[0];

// Now, in the widget's image property of your first example:
image: (imageUrl != null) // Only use the network image if the url is not null
  ? Image.network(
      imageUrl,
      loadingBuilder: (context, child, loadingProgress) =>
          (loadingProgress == null) ? child : CircularProgressIndicator(),
      errorBuilder: (context, error, stackTrace) => noImage,
    )
  : noImage;

这样您就可以处理图像数据无效异常,并在仍在获取网络图像时显示另一张图像。

PS:如果你想要加载资源后的淡入淡出效果,也可以使用FadeInImage.assetNetwork。

【讨论】:

感谢您的精彩回复。介意解释如何使用 FadeInImage.assetNetwork?我尝试用 Image.network 替换它,但 FadeInImage.assetNetwork 没有 errorBuilder 参数。谢谢! 不客气!你有一个例子right in the docs。要处理错误,您可以使用 _imageErrorBuilder_ 参数。正如我在上一个答案中提到的,您可能想了解更多关于 FadeInImage.assetNetwork here【参考方案2】:

CachedNetworkImage

您可以使用 cachedNetworkImage 代替图像网络。

 CachedNetworkImage(
                  imageUrl:
                      "https://store4.gofile.io/download/361b6d89-e4a7-4444-a725-a32bdbfefba6/WhatsApp%20Image%202021-11-03%20at%209.38.00%20PM.jpeg",
                  height: 25.h,
                  width: 100.w,
                  fit: BoxFit.fill,
                )

 CachedNetworkImage(
                  imageUrl: imageURL,
                  fit: BoxFit.fill,
                  placeholder: (context, url) => Padding(
                    padding: EdgeInsets.all(18.0),
                    child: CircularProgressIndicator(
                        strokeWidth: 2, color: MyColors.primary),
                  ),
                  errorWidget: (context, url, error) =>
                      Icon(Icons.person, color: MyColors.grey),
                )

【讨论】:

以上是关于try/catch 在网络图像上不起作用(例外:图像数据无效)的主要内容,如果未能解决你的问题,请参考以下文章

Web Share API 在 iOS 上不起作用:Angular

对于try catch放在能够很好地处理例外的位置

自定义后退按钮图像在导航栏上不起作用

转 js实践篇:例外处理Try{}catch(e){}

Cordova 背景图像在 Android 上不起作用 [关闭]

使用 AFNetworking 将图像保存在服务器上不起作用