一,概述

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. Apache Flink 进阶(八):详解 Metrics 原理与实战

    本文由 Apache Flink Contributor 刘彪分享,本文对两大问题进行了详细的介绍,即什么是 Metrics.如何使用 Metrics,并对 Metrics 监控实战进行解释说明. 什 ...

  2. [CF852H]Bob and stages

    题意:给出平面上\(n\)个点,要求选出\(k\)个点,使得这些点形成一个凸包,且凸包内部没有点,求最大面积.无解输出\(0\). 题解:枚举凸包最左的点\(p\),删除所有在\(p\)左边的点,然后 ...

  3. LOJ 2302 「NOI2017」整数——压位线段树

    题目:https://loj.ac/problem/2302 压30位,a最多落在两个位置上,拆成两次操作. 该位置加了 a 之后,如果要进位或者借位,查询一下连续一段 0 / 1 ,修改掉,再在含有 ...

  4. 基础复习之HTML (meta标签、块级元素与行内元素)

    一.meta标签 SEO 如何在不使用JS的情况下刷新页面(http-equiv="refresh" , content="time") 设置页面缓存 移动端设 ...

  5. 慕课-tooltip提示框总结

    在慕课上学Waynej老师的tooltip浮动提示框,老师每次讲课都会强调搬砖的流程,这点在上了老师的几节课后宝宝终于体会到了: 分析→设计→编码→优化 分析:分析该功能到底是怎样的,其实就是需求分析 ...

  6. Linux随笔 - Linux LVM逻辑卷配置过程详解[转载]

    许多Linux使用者安装操作系统时都会遇到这样的困境:如何精确评估和分配各个硬盘分区的容量,如果当初评估不准确,一旦系统分区不够用时可能不得不备份.删除相关数据,甚至被迫重新规划分区并重装操作系统,以 ...

  7. 用 Flask 来写个轻博客 (22) — 实现博客文章的添加和编辑页面

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 新建表单 新建视图函数 新建模板 在博客文章页面添加 New 和 Ed ...

  8. Could not resolve placeholder'XXX' in string value "XXXX"

    练习SSM项目的demo中遇到一个问题,我在applicationContext.xml中使用了<context:property-placeholder location="clas ...

  9. The Stream of Corning 2( 权值线段树/(树状数组+二分) )

    题意: 有两种操作:1.在[l,r]上插入一条值为val的线段 2.问p位置上值第k小的线段的值(是否存在) 特别的,询问的时候l和p合起来是一个递增序列 1<=l,r<=1e9:1< ...

  10. Vue2.0---webpack打包知识点-1

    打包上线或者将项目做成产品的肯定不希望暴露自己源码 在config的index.js中将productionGzip设置为false即可.(使之不生成.map文件). 对Vue-cli的webpack ...