build 方法多久调用一次?
Posted
技术标签:
【中文标题】build 方法多久调用一次?【英文标题】:How often is the build method called? 【发布时间】:2019-12-22 22:53:03 【问题描述】:我注意到 build 方法在 Flutter 应用中经常被调用。
我知道如果 statefulWidget 中的页面状态发生变化,就会触发 build 方法。但我也注意到,即使应用程序中没有任何更改,也会调用 build 方法。
考虑到您将应用程序留给自己的情况,频繁调用构建方法是否正常?如果是,为什么以及多久一次?
【问题讨论】:
答案很详细,但 TL;DR 版本是“考虑到它可能每秒被调用 60 次,总是这样,所以保持快速和幂等”。 【参考方案1】:为什么
每当您调用setState
、小部件的依赖项更新或任何父小部件被重新构建(当在这些小部件内部调用setState
时)时,都会调用构建方法。
您的小部件将取决于您使用的任何InheritedWidget
,例如Theme.of(context)
, MediaQuery.of(context)
等
这意味着如果主题发生变化或屏幕方向交换,您的小部件也将被重建。
当您使用框架提供的 MaterialApp
、Scaffold
等小部件时,您的小部件将被重建很多,因为这些父小部件依赖于许多 InheritedWidget
的然后被重建,这会导致你的小部件也被重建。
多久
没有多少重建是“正常”的,因为这完全取决于您的树大小,最重要的是小部件位于该树中。如果您要运行 runApp(Container())
,则不会进行重建。
请记住,所有这些重建可能都有充分的理由发生,Flutter 就是为此而构建的,因此您无需担心这一点。
您应该开始担心的唯一一点是,当您有可能由您使用不正确的某些构建器(内部调用 setState
)导致 不断 重建时。
确切的时候
documentation 列出了可能发生重建的所有特定情况:
拨打initState之后。 拨打didUpdateWidget之后。 接到setState的电话后。 在此 State 对象的依赖项发生更改后(例如,先前的 build 引用的 InheritedWidget 发生更改)。 在调用deactivate 然后将State 对象重新插入到树的另一个位置之后。从父小部件重建
如果您想了解InheritedWidget
的工作原理,请联系see this answer。当父小部件中的重建导致子树重建时,它也会涉及。
【讨论】:
所以页面的重建不依赖于fps + render?您认为当我将应用程序留给自己并且不更改任何内容时调用我的构建方法的原因是什么? @VahidZadeh 你的树中可能有一个builder
或一些setState
。您应该可以使用DevTools(小部件重建统计信息)进行调试。
它比这稍微复杂一些。像 LayoutBuilder 这样的东西可以出于完全不同的原因进行重建。而且“重建的父级”也不完全正确。它基于 Widget 的 == 运算符。
@RémiRousselet 我在考虑是否应该包含它,但我决定使用“重建”一词等于“用不同的小部件重建”,与某些数据不同改变了(==
如你所说)。 LayoutBuilder
重建的东西与调用 setState
的父小部件不同吗?
是的,LayoutBuilder 不同。该小部件构建在 RenderBox.layout 中。这是一个完全不同的机制【参考方案2】:
在调用 initState 之后。 调用 didUpdateWidget 之后。 在收到对 setState 的调用后。 在此 State 对象的依赖项发生更改后(例如,先前构建所引用的 InheritedWidget 发生更改)。 在调用 deactivate 然后将 State 对象重新插入到树中的另一个位置之后。
阅读本文了解更多信息https://api.flutter.dev/flutter/widgets/State/build.html
【讨论】:
以上是关于build 方法多久调用一次?的主要内容,如果未能解决你的问题,请参考以下文章
如果我经常调用 setneedsdisplay,drawrect 多久会被调用一次?这是为啥?
如果在循环中插入对象,应该多久调用一次 NSManagedObjectContext 保存?