「这是我参与11月更文挑战的第30天,活动详情查看:2021最终一次更文挑战」

Flutter中的WidgetAndroid中的ActivityiOS中的UIViewController一样,也是存在生命周期的,所谓的生命周期也就是回调函数,经过这些回调函数能够让咱们知道当前Widget所在的状况;

生命周期的作用

Widget出在不同的时间状况时,会有不同的生命周期回调函数履行,在这些回调函数中咱们能够做不同的工作:

  • 初始化数据
    • 变量和常量的创建
    • 网络恳求的发送
  • 监听Widget的事件
  • 内存的办理
    • 数据或许监听者的毁掉
    • 定时器TImer的毁掉

Widget的生命周期

众所周知,在FlutterWidget分为:有状况无状况两种,而且有状况Widget显着要比无状况Widget要复杂的多,那么他们的生命周期会不会有什么不同呢?

StatelessWidget的生命周期

咱们在界面上加载一个简单的StatelessWidget的页面,给页面传值title

Flutter(三十二)-Widget生命周期

Flutter(三十二)-Widget生命周期

很显着,咱们在Flutter中创建一个Widget的时分,运用的都是结构办法,比方此处的LessLifeCycleDemo的结构办法LessLifeCycleDemo(title: "无状况Widget生命周期"),而buildWidget烘托时会调用的办法;咱们分别在两个办法中增加打印信息:

Flutter(三十二)-Widget生命周期

这是StatelessWidget的生命周期,其相对简单;咱们接下来主要介绍一下StatefulWidget的生命周期;

StatefulWidget的生命周期

咱们编写如下代码,在咱们已知的生命周期办法中增加打印信息:

Flutter(三十二)-Widget生命周期

最终打印次序如下:

Flutter(三十二)-Widget生命周期

然后点击加号按钮:

Flutter(三十二)-Widget生命周期

在调用setState办法是,只要build办法会被触发履行;

现在咱们运用到的生命周期的函数还比较少,除了现在所用的,还有其他周期函数:

  • didChangeDependencies():当State目标的依赖发生变化是被调用;典型的场景就是系统语言改变或许主题发生变化时,Flutter结构会告诉Widget调用此回调;
  • reassemble():此回调只在开发调试的过程中生效,在热重载hot reload时被调用,在Release形式下永远不会回调;
  • didUpdateWidget():在Widget从头构建时,Flutter结构会调用widget.canUpdate来检测Widget树上同一方位的新旧两个节点,然后判断是否需求进行更新,假如返回true,则调用此回调;
    • widget.canUpdate会在新旧widgetkeyruntimeType一起相等时返回true;这个咱们在后边烘托原理时会讲到;
  • deactivate():当State目标从树中被移除时,会调用此回调;在某些场景下,Flutter结构会将State目标从头刺进到树中,比方包括此State目标的子树从树一个方位移动到另一个方位时(可经过GlobalKey来完成)。
    • 假如移除后,没有从头刺进到树中,则会直接调用dispose()办法进行毁掉;

触发build办法的场景

咱们都知道build办法在用于构建烘托Widget是会被调用,触发build办法有以下几个:

  • 调用initState()之后
  • 调用didUpdateWidget()之后
  • 调用setState()之后
  • 调用didChangeDependencies()之后
  • State目标从树的一个方位移除后(会调用deactivate()),又从头刺进到树的其他方位之后

setState触发build的本质

咱们都知道调用setState办法将会触发build办法的履行,那么为什么build办法会被履行呢?咱们来看一下setState的源码:

Flutter(三十二)-Widget生命周期

咱们能够看到setState办法的完成中,最重要的就是_element!.markNeedsBuild()办法,符号需求被烘托;那么_element是什么呢?咱们从上文代码中能够看到:

Flutter(三十二)-Widget生命周期

_element本质上就是BuildContext,那么咱们是否能够直接运用context调用markNeedsBuild办法来触发build呢?咱们将代码修改如下:

Flutter(三十二)-Widget生命周期

运转结果:

Flutter(三十二)-Widget生命周期

build办法被触发;

Android Studio中的一个bug

正常状况下,咱们在编译器中打印的生命周期的信息只会履行一次,比方咱们热重载的时分,办法履行如下:

Flutter(三十二)-Widget生命周期

但是,当咱们从头履行项目的时分,却会呈现下边的状况:

Flutter(三十二)-Widget生命周期

生命周期办法被调用了两次,这是Android Studio的一个bug,咱们能够运用Xcode来验证一下,在Xcode中直接运转项目是不会呈现这种状况的:

Flutter(三十二)-Widget生命周期