一,概述

Flutter 的生命周期分为两个部分:

  • Widget 的生命周期
  • App 的生命周期

二,Widget 的生命周期

Flutter 里的 Widget 分为 StatelessWidget 和 StatefulWidget 两种,这两种 Widget 的生命周期是不一样的,我们接下来具体来看。

  • StatelessWidget 的生命周期

    StatelessWidget 的生命周期只有一个,就是:

    • build

      build 是用来创建 Widget 的,但因为 build 在每次界面刷新的时候都会调用,所以不要在 build 里写业务逻辑,可以把业务逻辑写到你的 StatelessWidget 的构造函数里。

      StatelessWidget 的 build 函数代码如下:

      class TestWidget extends StatelessWidget{
      @override
      Widget build(BuildContext context) {
      // TODO: implement build
      print('StatelessWidget build');
      return Text('Test');
      }
      }
  • StatefulWidget 的生命周期

    • StatefulWidget 的生命周期比较复杂,依次为:

      • createState
      • initState
      • didChangeDependencies
      • build
      • addPostFrameCallback
      • didUpdateWidget
      • deactivate
      • dispose

    • 生命周期图
    • 接下来具体介绍一下各个生命周期。
      • createState

        createState 是 StatefulWidget 里创建 State 的方法,当要创建新的 StatefulWidget 的时候,会立即执行 createState,而且只执行一次,createState 必须要实现:

        class MyScreen extends StatefulWidget {
        @override
        _MyScreenState createState() => _MyScreenState();
        }
      • initState

        前面的 createState 是在创建 StatefulWidget 的时候会调用,initState 是 StatefulWidget 创建完后调用的第一个方法,而且只执行一次,类似于 Android 的 onCreate、iOS 的 viewDidLoad(),所以在这里 View 并没有渲染,但是这时 StatefulWidget 已经被加载到渲染树里了,这时 StatefulWidget 的 mount的值会变为 true,直到 dispose调用的时候才会变为 false。可以在 initState里做一些初始化的操作。

        在 override initState的时候必须要调用 super.initState():

        @override
        void initState() {
        super.initState();
        ...
        }
      • didChangeDependencies

        当 StatefulWidget 第一次创建的时候,didChangeDependencies方法会在 initState方法之后立即调用,之后当 StatefulWidget 刷新的时候,就不会调用了,除非你的 StatefulWidget 依赖的 InheritedWidget 发生变化之后,didChangeDependencies才会调用,所以 didChangeDependencies有可能会被调用多次。

        这个函数会紧跟在initState之后调用,并且可以调用BuildContext.inheritFromWidgetOfExactType,那么BuildContext.inheritFromWidgetOfExactType的使用场景是什么呢?最经典的应用场景是

        new DefaultTabController(length: 3, child: new TabBar(
        tabs: [ "主页","订单","我的" ]
        .map( (data)=>new Text(data) ).toList(),

        TabBar本来需要定义一个TabController,但是在外面套一层DefaultTabController就不需要定义TabContrller了,看下源码:

        @override
        void didChangeDependencies() {
        super.didChangeDependencies();
        _updateTabController();
        _initIndicatorPainter();
        } void _updateTabController() {
        final TabController newController = widget.controller ?? DefaultTabController.of(context);
        ...
        }

        注意到这里DefaultTabController.of(context)

        static TabController of(BuildContext context) {
        final _TabControllerScope scope = context.inheritFromWidgetOfExactType(_TabControllerScope);
        return scope?.controller;
        }

        实际上就是调用BuildContext.inheritFromWidgetOfExactType,也就说在didChangeDependencies中,可以跨组件拿到数据。

      • build

        在 StatefulWidget 第一次创建的时候,build方法会在 didChangeDependencies方法之后立即调用,另外一种会调用 build方法的场景是,每当 UI 需要重新渲染的时候(setState触发),build都会被调用,所以 build会被多次调用,然后 返回要渲染的 Widget。千万不要在 build里做除了创建 Widget 之外的操作,因为这个会影响 UI 的渲染效率。

      • addPostFrameCallback

        addPostFrameCallback是 StatefulWidge 渲染结束的回调,只会被调用一次,之后 StatefulWidget 需要刷新 UI 也不会被调用,addPostFrameCallback的使用方法是在 initState里添加回调:

        import 'package:flutter/scheduler.dart';
        @override
        void initState() {
        super.initState();
        SchedulerBinding.instance.addPostFrameCallback((_) => {});
        }
      • didUpdateWidget

        祖先节点rebuild widget时调用 .当组件的状态改变的时候就会调用didUpdateWidget.(可能会调用多次)

        理论上setState的时候会调用,但我实际操作的时候发现只是做setState的操作的时候没有调用这个方法。而在我改变代码hot reload时候会调用 didUpdateWidget 并执行 build…

        实际上这里flutter框架会创建一个新的Widget,绑定本State,并在这个函数中传递老的Widget。这个函数一般用于比较新、老Widget,看看哪些属性改变了,并对State做一些调整。

        需要注意的是,涉及到controller的变更,需要在这个函数中移除老的controller的监听,并创建新controller的监听。

      • deactivate(组件移除时)

        当要将 State 对象从渲染树中移除的时候,就会调用 deactivate生命周期,这标志着 StatefulWidget 将要销毁,但是有时候 State 不会被销毁,而是重新插入到渲染树种。

      • dispose(组件移除时)

        当 View 不需要再显示,从渲染树中移除的时候,State 就会永久的从渲染树中移除,就会调用 dispose生命周期,这时候就可以在 dispose里做一些取消监听、动画的操作,和 initState是相反的。

三,App 的生命周期

AppLifecycleState 就是 App 的生命周期,有:

  • resumed
  • inactive
  • paused
  • suspending

如果想要知道 Flutter App 的生命周期,例如 Flutter 是在前台还是在后台,就需要使用到 WidgetsBindingObserver了,使用方法如下:

  1. State 的类 mix WidgetsBindingObserver:

    class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
    ...
    }
  2. 在 State 的 initState里添加监听:

    @override
    void initState(){
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    }
  3. 在 State 的 dispose里移除监听:

     @override
    void dispose() {
    // TODO: implement dispose
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
    }
  4. 在 State 里 override didChangeAppLifecycleState

    @override
    void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.paused) {
    // went to Background
    }
    if (state == AppLifecycleState.resumed) {
    // came back to Foreground
    }
    }

【Flutter学习】之 Flutter 的生命周期的更多相关文章

  1. 【老孟Flutter】Stateful 组件的生命周期​

    老孟导读:关于生命周期的文章共有2篇,第一篇是介绍 Flutter 中Stateful 组件的生命周期. 博客地址:http://laomengit.com/blog/20201227/Statefu ...

  2. MAVEN学习笔记之Maven生命周期和插件简介(3)

    MAVEN学习笔记之Maven生命周期和插件简介(3) clean compile site三套生命周期相互独立. clean pre-clean 执行清理前的工作 clean 清理上一次构建生成的所 ...

  3. Flutter学习(9)——Flutter插件实现(Flutter调用Android原生

    原文地址: Flutter学习(9)--Flutter插件实现(Flutter调用Android原生) | Stars-One的杂货小窝 最近需要给一个Flutter项目加个apk完整性检测,需要去拿 ...

  4. Maven学习(四)-- 生命周期和插件

    标签(空格分隔): 学习笔记 Maven生命周期是抽象的,不做任何实际的工作,在Maven的设计中,实际的任务都交由插件来完成. 每个构件步骤都可以绑定一个或者多个插件行为,而且Maven为大多数构建 ...

  5. Android学习整理之Activity生命周期篇

    一.Activity生命周期说明   Activity的四种状态: ⒈活动状态(Active or Running):也称为运行状态,处于Activity栈顶,在用户界面中最上层,完全能被用户看到,能 ...

  6. IOS学习笔记37——ViewController生命周期详解

    在我之前的学习笔记中讨论过ViewController,过了这么久,对它也有了新的认识和体会,ViewController是我们在开发过程中碰到最多的朋友,今天就来好好认识一下它.ViewContro ...

  7. Maven学习笔记(六):生命周期与插件

    何为生命周期:      Maven的生命周期就是为了对全部的构建过程进行抽象和统一.Maven从大量项目和构建工具中学习和反思,然后总结了一套高度完好的.易扩展的生命周期.这个生命周期包括了项目的清 ...

  8. Vue学习系列(四)——理解生命周期和钩子

    前言 在上一篇中,我们对平时进行vue开发中遇到的常用指令进行归类说明讲解,大概已经学会了怎么去实现数据绑定,以及实现动态的实现数据展示功能,运用指令,可以更好更快的进行开发.而在这一篇中,我们将通过 ...

  9. Spring4学习笔记 - Bean的生命周期

    1 Spring IOC 容器对 Bean 的生命周期进行管理的过程: 1)通过构造器或工厂方法创建 Bean 实例 2)为 Bean 的属性设置值和对其他 Bean 的引用 3)调用 Bean 的初 ...

  10. Maven学习(三)生命周期

    maven有三套生命周期 1.clean       清理项目 2.default     构建项目 3.site           建立项目站点 每套生命周期都包含了一些阶段,这些阶段是有序的,后 ...

随机推荐

  1. 4412 GPIO初始化

    一.GPIO的初始化 • 在内核源码目录下使用命令“ls drivers/gpio/*.o”,可以看到“gpioexynos4”被编译进了内核.通过搜索*.o文件,可以知道内核编译内哪些文件.针对的看 ...

  2. Python读取文件时出现UnicodeDecodeError 'gbk' codec can't decode byte 0x80 in position x

    Python在读取文件时 with open('article.txt') as f: # 打开新的文本 text_new = f.read() # 读取文本数据出现错误: UnicodeDecode ...

  3. NAGIOS(网络监视工具)

    Nagios是一款开源的免费网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机,路由器等网络设备,打印机等.在系统或服务状态异常时发出邮件或短信报警第一时间通知网站运维人员 ...

  4. 2018-2019 2 20165203 《网络对抗技术》Exp9 Web安全基础

    2018-2019 2 20165203 <网络对抗技术>Exp9 Web安全基础 实验要求 本实践的目标理解常用网络攻击技术的基本原理,做不少于7个题目,共3.5分.包括(SQL,XSS ...

  5. HDU 3183 A Magic Lamp(RMQ问题, ST算法)

    原题目 A Magic Lamp Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. 深入浅出HashMap

    /** *@ author ViVi *@date 2014-6-11 */ Hashmap是一种非常常用的.应用广泛的数据类型,最近研究到相关的内容,就正好复习一下.希望通过仪器讨论.共同提高~ 1 ...

  7. 使用Excel绘制F分布概率密度函数图表

    使用Excel绘制F分布概率密度函数图表 利用Excel绘制t分布的概率密度函数的相同方式,可以绘制F分布的概率密度函数图表. F分布的概率密度函数如下图所示: 其中:μ为分子自由度,ν为分母自由度 ...

  8. 小程序BUTTON点击,去掉背景色

    添加hover-class <button form-type="submit"  hover-class="btn-hover"></but ...

  9. 关于日历实现代码里lunarInfo(农历)数组

    var lunarInfo=new Array( 0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x0 ...

  10. shell zip和unzip压缩和解压,压缩效率

    1.把/home目录下面的mydata目录压缩为mydata.zip zip -r mydata.zip mydata #压缩mydata目录zip -r mydata.zip ./*txt #压缩当 ...