为什么根Widget会被构建两次?

10

我有一个非常基本的测试应用程序:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    print("ROOT WIDGET ");
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Container(decoration: BoxDecoration(color: Colors.blue),),
    );
  }
}

日志输出调试:

在debug模式下启动iPhone X上的lib/main.dart...

找到已保存的证书选择“XXX”。要清除,请使用“flutter config”。 使用开发人员身份验证签署iOS应用程序以进行设备部署:“XXX”

正在运行Xcode构建...

Xcode构建完成。 39,4s

安装并启动...

flutter:ROOT WIDGET

将文件同步到设备iPhone X...

flutter:ROOT WIDGET

使用flutter run --release的日志输出

在release模式下启动iPhone X上的lib/main.dart...

找到已保存的证书选择“XXX”。要清除,请使用“flutter config”。

使用开发人员身份验证签署iOS应用程序以进行设备部署:“XXX”

正在运行pod install...
1.2秒

正在运行Xcode构建...
├─构建Dart代码... 15.8秒

├─生成dSYM文件... 0.1秒

├─剥离调试符号... 0.0秒

├─组装Flutter资源... 0.7秒

└─编译、链接和签名... 48.3秒

Xcode构建完成。 67.4秒

安装并启动...
6.8秒钟

要退出,请按“q”。

flutter:ROOT WIDGET

正如您所看到的,这仅在调试模式下发生。

我之所以问,是因为在我的实际应用中,我使用了WebViewWebViewonWebViewCreated(WebViewController controller)函数只被调用一次,因此在调试模式下始终为null。


1
这没关系,你不必担心。如果它给你带来了问题,那么很可能是你在_build_方法中做了一些不应该做的事情。请参考https://dev59.com/71QK5IYBdhLWcg3wNtTA - Rémi Rousselet
谢谢您的快速回答,但是正如您所看到的,我在我的构建方法中基本上什么都没有做。 - 最白目
哦,我想我明白你的意思了,在另一个应用中,我在构建方法中初始化了 webView,这可能是我不应该做的事情。但是,我必须在某个地方初始化我的 webView,如果不是在构建方法中,那应该在哪里呢? - 最白目
很可能就是这样了 :) 你需要在_initState_或类似的地方执行此操作。 - Rémi Rousselet
1
@Alexander Semenov 是的,在这种特定情况下,我们只在initState方法中初始化了webview,问题就不再出现了。 - 最白目
显示剩余3条评论
3个回答

7

我一直在遇到这个问题:

Flutter 1.22.0 • 渠道 稳定版

从模拟器/物理手机上删除应用程序并重新安装可以解决该问题。请从系统设置/应用程序中删除模拟器/物理设备上的应用程序,并以调试模式重新安装。

我不知道原因,但有时我的主要小部件会被重建两次,而且我没有在主要小部件中执行任何State改变或FutureBuilder操作。我认为这是Flutter内部的一个错误。


1

线索可能在这里

Installing and launching... //We are launching the app , the code bundled with it it's executed briefly before it "sync" to allow hot reload

flutter: ROOT WIDGET //The bundled code executes

Syncing files to device iPhone X... //We start the sync, hot reload triggers an app rebuild 

flutter: ROOT WIDGET //The live code executes

如果您注释掉打印语句,然后进行热重载,再取消注释打印语句,您应该只能看到一个“ROOT WIDGET”。

-3

我有同样的问题,我发现这不是Flutter的问题,而是vscode的问题。尝试在Android Studio中运行。


它如何帮助解决问题中的环境问题? - s0xzwasd
我不确定,也许我的回答与此问题无关。但是当我使用VSCode时,每次应用程序构建两次。这种情况在Android Studio上没有发生。 - Ershat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接