【问题标题】:How to prevent making more URL request after an image is already downloaded via Internet?图片中有值后如何防止发出更多的URL请求?
【发布时间】:2022-10-14 11:00:24
【问题描述】:
  var alreadyDdl = false;

  getLogoUrl(context) async {
    if(!alreadyDdl) {
      final db = Localstore.instance;
      final data = db.collection('inputs').doc("1").get();
      var database = (await data)["content"].toString();
      var form = new DGForm("project/getwebsitelogo", {"database": database});
      var ret = await form.urlGET(context);
      ResponseObject responseObject =
      ResponseObject.fromJson(json.decode(ret.body));
      print("hola");
      var hola = (responseObject.datas[0][0].toString());
      bandeauDuClient = hola;
      print(hola);
      return hola;
    }
  }

   getLogoUrl(context).then((val) {
      setState(() => 
       logoUrl = val
      );
      alreadyDdl = true;
    });

永远不会在小部件构建中向我显示服务器下载的图像

(logoUrl != null) ? Image.network(logoUrl): Image.asset('assets/none.png') 

因此,当我删除代码中的所有 alreadyDdl 变量时,......它每毫秒都会向我发送一个 http 请求......我想在图像真正下载后停止 http 请求......

【问题讨论】:

  • 发布更多代码,因为我们无法确定该代码在哪里?如果它在 build 方法中,那么它可能会在每次新框架准备好时调用。您应该在 initState 中调用此函数
  • 是的,我可以确认,它是Widget build(BuildContext context) { 方法,你还需要吗?

标签: flutter asynchronous async-await


【解决方案1】:

使用此包加载图像 url 它将避免不必要的请求

https://pub.dev/packages/cached_network_image

并检查您的整个代码是否有不必要或重复的状态刷新

【讨论】:

    【解决方案2】:

    您可以使用 Future 构建器基于与 Future 交互的最新快照创建小部件。您可以按照上面的建议将它与 cached_network_image 包结合使用。

    这是一个示例代码,演示了这一点:

    import "package:flutter/material.dart";
    //Your other imports...
    
    class MyApp extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return _MyApp();
      }
    }
    
    class _MyApp extends State<MyApp> {
      var db;
    
      @override
      initState() {
        db = Localstore.instance;
      }
    
      getLogoUrl(context) async {
        final data = db.collection('inputs').doc("1").get();
        var database = (await data)["content"].toString();
        var form = new DGForm("project/getwebsitelogo", {"database": database});
        var ret = await form.urlGET(context);
        ResponseObject responseObject =
            ResponseObject.fromJson(json.decode(ret.body));
        print("hola");
        var hola = (responseObject.datas[0][0].toString());
        bandeauDuClient = hola;
        print(hola);
        return hola;
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: FutureBuilder(
            future: getLogoUrl(context),
            builder: (ctx, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                // if we got our data
                if (snapshot.hasData) {
                  return CachedNetworkImage(
            imageUrl: snapshot.data,
            progressIndicatorBuilder: (context, url, downloadProgress) => 
                    CircularProgressIndicator(value: downloadProgress.progress),
            errorWidget: (context, url, error) => Icon(Icons.error),
         );
                } else {
                  // If we probably got an error check snapshot.hasError
                  return Center(
                    child: Text(
                      '${snapshot.error} occurred',
                      style: TextStyle(fontSize: 18),
                    ),
                  );
                }
              } else {
                return const CircularProgressIndicator();
              }
            },
          ),
        );
      }
    }
    
    

    注意:永远不要在 build 方法中进行网络调用,因为 build 方法通常每秒调用 60 次来渲染。在 initState 或像 FutureBuilder 这样为您处理这些事情的小部件中进行网络调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-30
      • 2013-09-14
      • 2022-01-16
      • 2019-10-05
      • 1970-01-01
      • 1970-01-01
      • 2020-05-09
      相关资源
      最近更新 更多