【问题标题】:Image.network throw error even after defining errorBuilder in Flutter即使在 Flutter 中定义了 errorBuilder,Image.network 也会抛出错误
【发布时间】:2022-08-16 16:15:12
【问题描述】:

我在 Flutter 中从 URL 加载图像时遇到了一些问题。这是我的代码:

  @override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: BorderRadius.circular(8.0),
      child: Center(
        child: Image.network(
          \'https://www.example.com/no-image.jpg\', // this image doesn\'t exist
          fit: BoxFit.cover,
          errorBuilder: (context, error, stackTrace) {
            return Container(
              color: Colors.amber,
              alignment: Alignment.center,
              child: const Text(
                \'Whoops!\',
                style: TextStyle(fontSize: 30),
              ),
            );
          },
        ),

      ),
    );
  }

我正在使用Image.network 从给定的 URL 接收图像,但由于 URL 不存在,即使定义了 errorBuilder 参数,小部件也会引发 404 异常。它不仅适用于 404 异常,还适用于任何网络连接错误。

异常来源(颤振文件:.../_network_image_io.dart):

Future<ui.Codec> _loadAsync(
    NetworkImage key,
    StreamController<ImageChunkEvent> chunkEvents,
    image_provider.DecoderCallback decode,
  ) async {
    try {
      assert(key == this);

      final Uri resolved = Uri.base.resolve(key.url);

      final HttpClientRequest request = await _httpClient.getUrl(resolved);

      headers?.forEach((String name, String value) {
        request.headers.add(name, value);
      });
      final HttpClientResponse response = await request.close();
      if (response.statusCode != HttpStatus.ok) {
        // The network may be only temporarily unavailable, or the file will be
        // added on the server later. Avoid having future calls to resolve
        // fail to check the network again.
        await response.drain<List<int>>(<int>[]);
        throw image_provider.NetworkImageLoadException(
            statusCode: response.statusCode, uri: resolved);
      }

      final Uint8List bytes = await consolidateHttpClientResponseBytes(
        response,
        onBytesReceived: (int cumulative, int? total) {
          chunkEvents.add(ImageChunkEvent(
            cumulativeBytesLoaded: cumulative,
            expectedTotalBytes: total,
          ));
        },
      );
      if (bytes.lengthInBytes == 0)
        throw Exception(\'NetworkImage is an empty file: $resolved\');

      return decode(bytes);
    } catch (e) {
      // Depending on where the exception was thrown, the image cache may not
      // have had a chance to track the key in the cache at all.
      // Schedule a microtask to give the cache a chance to add the key.
      scheduleMicrotask(() {
        PaintingBinding.instance!.imageCache!.evict(key);
      });
      print(e);
      rethrow; // <<<<<<<< Exception throw here: NetworkImageLoadException (HTTP request failed, statusCode: 404, https://www.example.com/no-image.jpg)
    } finally {
      chunkEvents.close();
    }
  }

我想知道这是一个错误还是我犯了一个错误。

  • 它不会向我抛出错误。
  • 好吧,那是有线@DipakPrajapati
  • 图片 URL 对我来说很好用,你能和问题一起分享这个例外吗?
  • 我发现它只是一个调试异常并且可以被忽略,所以我的问题已经解决了。感谢您的评论@ibhavikmakwana

标签: android ios flutter image networking


【解决方案1】:

我已经使用 errorBuilder 处理了与 404 相关的网络图像问题。

Image.network('Your image url...',
        errorBuilder: (BuildContext context, Object exception, StackTrace stackTrace) {
            return Text('Your error widget...');
        },
    ),

【讨论】:

    【解决方案2】:

    是的,您对实施是正确的。所以问题是,NetworkImage 尝试加载图像并且无法加载它。因此,_loadAsync() 方法 rethrows 例外。现在,正如您提供的errorBuilder,框架使用该小部件来显示何时发生异常。因此,您会得到一个从框架中重新抛出的异常,但会按照您提供的errorBuilder 进行处理。现在,如果您删除errorBuilder,您将在调试控制台中记录异常,并且用户将能够在调试模式下看到红色异常屏幕,在发布模式下看到灰色屏幕。

    所以,你的实现和你的疑问都是正确的,但是你错过了errorBuilder 的确切解释。

    我希望这能澄清你的疑问!

    【讨论】:

    • 这个答案根本没有帮助。它只是一步一步地说明正在发生的事情,但并不能以这种方式给出答案。 OP 有一个问题,errorBuilder 没有被调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-22
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多