0

在我的应用程序中,用户会看到一个拼图,该拼图由 Flutter 的 CustomerPainter 类的重新实现绘制,并接受通过点击 Canvas 做出的动作。画布不断更新和重新绘制以显示动作。当用户做出最后一步并完成正确的解决方案时,应用程序应该告诉用户。该应用程序正在使用 Flutter 的 AlertDialog 向用户发出此类消息。

问题在于,当检测到解决方案情况时,应用程序深入 CustomPainter 的 paint() 方法。任何在此时发出消息的尝试都会导致应用程序崩溃。给用户的消息确实出现了,但到那时应用程序已经崩溃了。错误消息是:
[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception:
setState() or markNeedsBuild() called during build.

[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception:
Build scheduled during frame.

这些信息之后是关于发生了什么以及应该做什么的全面建议。Stack Overflow 上也有一些建议,但我无法让它们中的任何一个起作用。

如果我在我的小部件构建中编写 SchedulerBinding.instance.addPostFrameCallback 它将无法编译,因为它需要来自 BindingBase 的几个部分。SchedulerBinding 是一个 mixin。如果我尝试将 BindingBase 混入到我的 Widget,编译将再次失败,因为 BindingBase 是一个类,具有构造函数,而不是混入。

如果我采用异步方式,使用 Future executeAfterBuild(),应用程序编译但再次崩溃,显然是因为异步函数立即执行(正常)并且没有在小部件构建之后安排,正如一些堆栈中所建议的那样溢出帖子。该应用程序在崩溃时肯定不在 setState() 中,因此可能 markNeedsBuild() 以某种方式触发了崩溃。

我正在使用 Flutter 2.8.2 和 Dart 2.15.1,以及健全的 null 安全性。Flutter 的小部件调度策略是否发生了变化?我提到的 Stack Overflow 帖子已经有 3 年的历史了。

4

1 回答 1

0

您是否尝试过将 setState 放入:

WidgetsBinding.instance?.addPostFrameCallback((_) {setState((){});})
于 2022-02-07T08:15:12.337 回答