flutter 生命周期

2023-11-06

生命周期似乎已经成为前端框架的标配了,然后在flutter中依然有生命周期这个概念。

flutter是一个组件加载到卸载的整个周期,不同的生命周期内可以做的事情都是不一样,相信使用过react,vue的小伙伴应该都清楚,在更新组件的时候在相应生命周期相业务逻辑、初始化页面的时候做一些数据处理等等。

 

废话不多说,先上flutter的生命周期图:

 

flutter生命周期.png

 

初始化时会依次执行:构造函数 > initState > didChangeDependencies > Widget build

当组件state值改变时,依次执行 didUpdateWidget > Widget build

 

initState() {} 初始化state值,在实例化的时候,就会执行只方法函数,只会触发1次。

 

didUpdateWidget(oldWidget) {}当组件状态改变时触发,它会返回一个旧的widget组件

didChangeDependencies() {} 会紧跟在initState之后调用,当依赖的InheritedWidget更新state值时,会触发此生命周期

更新分为两种更新:

一种是组件本身或者其父组件调用setState触发的更新,这种更新走的生命周期是:didUpdateWidget->build。

这没什么说的,我们可以在didUpdateWidget重新绑定一些组件的监听或者重置状态。

另一种是依赖的InheritedWidget发生变化的时候,会触发didChangedDependencies。

 

Widget build(BuildContext context) {} 渲染页面组件,调用次数:多次

 

deactivate() {}方法标志组件为无效状态,在组件被卸载移除之前触发(当前组件还可渲染读取),都是在dispose生命周期前执行的。

dispose() {} 组件被卸载后触发,用于监听组件卸载后去处理清理等操作,调用次数1reassemble() {}此回调是专门为了开发调试而提供的,在热重载(hot reload)时会被调用,此回调在Release模式下永远不会被调用

didChangeAppLifecycleState(AppLifecycleState state) {}获取App的生命周期,此生命周期内可以获取用户不同状态的生命周期,此方法必须继承

WidgetsBindingObserver接口后才可以使用
AppLifecycleState.resumed可见并能响应用户的输入

AppLifecycleState.inactive处在并不活动状态,无法处理用户响应

AppLifecycleState.paused不可见并不能响应用户的输入,但是在后台继续活动中

 

代码打印这些方法在何时执行(测试生命周期)
import 'package:flutter/material.dart';
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
  _MyHomePageState() {
    print('构造函数');
  }

  @override
  void initState() {
    // 初始化state值,在实例化的时候
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    print('initState');
  }

  @override
  void didChangeDependencies() {
    // 当依赖的InheritedWidget 更新state值时,会触发此生命周期
    super.didChangeDependencies();
    print('didChangeDependencies');
  }

  // 如果想要知道App的生命周期,那么需要通过WidgetsBindingObserver的didChangeAppLifecycleState 来获取
  // 通过此生命周期获取APP中的一些其它生命周期
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    print(state.toString());
    /* 
      resumed   可见并能响应用户的输入
      inactive  处在并不活动状态,无法处理用户响应
      paused    不可见并不能响应用户的输入,但是在后台继续活动中
     */
    if (state == AppLifecycleState.resumed) {
      print('可见并能响应用户的输入');
    }
  }

  @override
  void didUpdateWidget(oldWidget) {
    // 当组件状态改变时触发
    super.didUpdateWidget(oldWidget);
    print('didUpdateWidget');
  }

  @override
  void reassemble() {
    // 在热重载(hot reload)时会被调用
    super.reassemble();
    print('reassemble');
  }

  @override
  void deactivate() {
    // 在组件被卸载之前触发(当前组件还可渲染读取)
    super.deactivate();
    print('deactivate');
  }

  @override
  void dispose() {
    // 组件被卸载时触发
    super.dispose();
    WidgetsBinding.instance.addObserver(this);
    print('dispose');
  }

  @override
  Widget build(BuildContext context) {
    print('build');
    // TODO: implement build
    return MaterialApp(
      home: Center(
          child: GestureDetector(
        child: new Text('lifeCycle'),
        onTap: () {
          Navigator.of(context)
              .push(new MaterialPageRoute(builder: (BuildContext c) {
            return new Text('sdfs');
          }));
        },
      )),
    );
  }

}

import 'package:flutter/material.dart';
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
 
class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
  _MyHomePageState() {
    print('构造函数');
  }
 
  @override
  void initState() {
    // 初始化state值,在实例化的时候
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    print('initState');
  }
 
  @override
  void didChangeDependencies() {
    // 当依赖的InheritedWidget 更新state值时,会触发此生命周期
    super.didChangeDependencies();
    print('didChangeDependencies');
  }
 
  // 如果想要知道App的生命周期,那么需要通过WidgetsBindingObserver的didChangeAppLifecycleState 来获取
  // 通过此生命周期获取APP中的一些其它生命周期
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    print(state.toString());
    /* 
      resumed   可见并能响应用户的输入
      inactive  处在并不活动状态,无法处理用户响应
      paused    不可见并不能响应用户的输入,但是在后台继续活动中
     */
    if (state == AppLifecycleState.resumed) {
      print('可见并能响应用户的输入');
    }
  }
 
  @override
  void didUpdateWidget(oldWidget) {
    // 当组件状态改变时触发
    super.didUpdateWidget(oldWidget);
    print('didUpdateWidget');
  }
 
  @override
  void reassemble() {
    // 在热重载(hot reload)时会被调用
    super.reassemble();
    print('reassemble');
  }
 
  @override
  void deactivate() {
    // 在组件被卸载之前触发(当前组件还可渲染读取)
    super.deactivate();
    print('deactivate');
  }
 
  @override
  void dispose() {
    // 组件被卸载时触发
    super.dispose();
    WidgetsBinding.instance.addObserver(this);
    print('dispose');
  }
 
  @override
  Widget build(BuildContext context) {
    print('build');
    // TODO: implement build
    return MaterialApp(
      home: Center(
          child: GestureDetector(
        child: new Text('lifeCycle'),
        onTap: () {
          Navigator.of(context)
              .push(new MaterialPageRoute(builder: (BuildContext c) {
            return new Text('sdfs');
          }));
        },
      )),
    );
  }
 
}
以上代码自己在模拟器上运行打印出相应生命周期

 

以下总结运行输出打印结果:

1、创建一个wedget到显示 打印输出依次如下,initState》》didChangeDependencies》》build

2、退出页面依次输出:deactivate》》dispose

3、点击热重载按钮,依次输出:reassemble》》didUpdateWidget》》build

4、app由显示切换到后台(home状态),依次输出:AppLifecycleState.inactive》》AppLifecycleState.paused

5、app由后台切回前台,依次输出: AppLifecycleState.inactive》》AppLifecycleState.resumed

App切换后台状态
在app切换后台,以及切换回当前页面时也有相应监听生命周期,不过这是需要继承WidgetsBindingObserver 才能获取到的,具体如下:

// ...省略
class _MyListState extends State<MyList> with WidgetsBindingObserver {
    @override
    void initState() {
    super.initState();
      WidgetsBinding.instance.addObserver(this); // 监听
    }

    // 通过此生命周期获取APP中的一些其它生命周期
    @override
    void didChangeAppLifecycleState(AppLifecycleState state) {
      print(state.toString());
      switch (state) {
        case AppLifecycleState.inactive: 
    // 处于这种状态的应用程序应该假设它们可能在任何时候暂停。
          break;
        case AppLifecycleState.resumed: // 应用程序可见,前台
          break;
        case AppLifecycleState.paused: // 应用程序不可见,后台
          break;
        case AppLifecycleState.detached: // 申请将暂时暂停
          break;
        default:
          break;
      }
    }
}

// ...省略
class _MyListState extends State<MyList> with WidgetsBindingObserver {
    @override
    void initState() {
    super.initState();
      WidgetsBinding.instance.addObserver(this); // 监听
    }
 
    // 通过此生命周期获取APP中的一些其它生命周期
    @override
    void didChangeAppLifecycleState(AppLifecycleState state) {
      print(state.toString());
      switch (state) {
        case AppLifecycleState.inactive: 
    // 处于这种状态的应用程序应该假设它们可能在任何时候暂停。
          break;
        case AppLifecycleState.resumed: // 应用程序可见,前台
          break;
        case AppLifecycleState.paused: // 应用程序不可见,后台
          break;
        case AppLifecycleState.detached: // 申请将暂时暂停
          break;
        default:
          break;
      }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

flutter 生命周期 的相关文章

  • Android ToggleButton 始终检查

    如果切换按钮处于选中或取消选中状态 我想存储在 SharedPreferences 中 toggle setOnCheckedChangeListener new OnCheckedChangeListener public void on
  • 在 dart 的 MultipartRequest 中添加授权标头

    我在用多部分请求 https pub dartlang org documentation http latest http MultipartRequest class html在 Dart 中以便将文件上传到 API 但是我需要在我的请
  • 为什么不能在 Fragment 中使用 ViewPager?它实际上是

    有信息无法使用ViewPager在一个Fragment在许多来源中 例如 Android 开发者繁忙编码指南 http commonsware com 作者 Mark Murphy 或者类似的帖子this https stackoverfl
  • 无法在 Android Studio 中导出签名的 APK

    当我使用keytool list keystore path to keyfile jks并提供我的密码 我可以看到那里的条目 但是当我在尝试使用相同的密码生成签名的 APK 时使用相同的密码时 我收到错误 无法加载密钥库 密钥库被篡改 或
  • Android 中使用黑白 alpha 蒙版的高效位图蒙版

    我想用黑白 alpha 蒙版来掩盖位图 我的蒙版图像是黑白的 黑色区域意味着透明 白色区域意味着不透明 我需要的是 当我使用此蒙版图像来蒙版任何其他图像时 如果蒙版图像的相应区域为黑色 则生成的图像区域应为透明 否则 生成的图像区域应该是不
  • 嵌套 XML 布局文件

    android 有没有办法从另一个布局文件引用 xml 布局文件 为了更好地解释 我有一个名为layout1 xml 和layout2 xml 的布局文件 我可以从layout1 xml引用layout2 xml吗 用这个
  • 4 天后,应用仍未在 Google Play 搜索中编入索引

    我已经在 4 天前在 google play 上发布了我的第一个应用程序 语音到短信 但我仍然无法通过其名称或开发人员名称在搜索中找到我的应用程序 我只能通过包名称或真实应用程序名称 但不带空格 找到我的应用程序 VoiceToSMS 链接
  • relativelayout导致动画不起作用?

    我有一个活动 其布局仅包含一个 VideoView 这是 XML
  • 如何清除Android剪贴板?

    我发现的方法都不起作用 这是我尝试过的 1 使用clearPrimaryClip 的方法ClipboardManager class ClipboardManager clipboard ClipboardManager getSystem
  • Android 和 Google 地图内部片段以及其他控件和 viewpager

    我是android编程新手 我有一个带有 3 个页面 片段 的小应用程序 使用 pageradapter 和 viewpager 在它们之间滑动 其中一个页面包含复选框 和其他控件 和地图 我的问题是程序在启动时崩溃 Fragment co
  • 在光标所在行强制关闭!

    嘿 我正在尝试创建一个应用程序来查找存储在 SQlite 数据库中的 GPS 数据 但我面临一个问题 我构建了一个 DbAdapter 类来创建数据库 现在我尝试使用以下函数从另一个类获取所有数据上的光标 public Cursor fet
  • 在 Android 中加密/解密字符串的简单方法

    我的问题是如何加密String String AndroidId Override public void onCreate Bundle savedInstanceState super onCreate savedInstanceSta
  • Android:WebView/BaseInputConnection 中的退格键

    我在 Android 4 2 中遇到软键盘退格问题 我在 WebView CodeMirror 中有一个自定义编辑器 它使用一个空的
  • Android Google Map V2:如何在单击另一个标记时更改先前单击的标记的图标

    更新 我通过添加 previousMarker 对象解决了性能问题 因此 只有先前单击的标记将被删除并替换为默认图标 但是 当我单击标记时 信息窗口仍然不显示 我有一个地图视图并在上面设置了一些标记 我想要的是 当我单击一个标记时 它将其图
  • Android 的 Intent 和 Parcelable 对象

    为什么我需要打包我的对象 即使我只需将其发送到同一任务的另一个线程 实际上 我需要打开一个甚至可以在同一线程 主线程 上运行的活动 换句话说 为什么 Google 不提供一个 startActivity 版本 它采用通用对象广告参数而不是捆
  • 以 HTML 格式发送电子邮件

    我想发送 HTML 格式的电子邮件 如下图所示 我怎样才能做到这一点 请帮我 提前致谢 String body new String table tr td br header td tr br br Get b Best Score b
  • 如何知道我的应用程序的活动计数?

    我的应用程序中有多项活动 请考虑以下案例 Activity A 调用 Activity B B 调用 C 当用户按后退键时 C 生成通知并转到 B 现在再次按后退 因此将显示 A 再次按后退键也会终止 A 并显示通知 现在 当用户按下通知图
  • 通过 Gradle 和 Android Studio 构建和运行应用程序比通过 Eclipse 慢

    我有一个多项目 10 个模块 每次构建大约需要 20 30 秒 当我在 Android Studio 中按 运行 时 每次都必须等待才能重建应用程序 这非常慢 是否可以在 Android Studio 中自动化构建过程 或者您对如何加快此过
  • 动态更改按钮上的图像视图

    在我的应用程序中 我有按钮和ImageView 当我按下按钮时我想改变ImageView 我的可绘制文件夹中有 5 张图像 按下按钮时 ImageView 根据按钮单击一张一张地更改图像 我想要它的解决方案 感谢任何可以提供帮助的人 维护一
  • 如何从DataSource.Factory获取数据

    我必须调用此方法才能获取所有人员 我根本无法修改这个方法 Query SELECT FROM PERSON TABLE ORDER BY NAME DESC abstract fun getElements DataSource Facto

随机推荐

  • AI虚拟点读机--详细注释解析恩培作品7

    感谢恩培大佬对项目进行了完整的实现 并将代码进行开源 供大家交流学习 一 项目简介 本项目最终达到的效果为手势控制虚拟点读机 如下所示 项目用python实现 调用opencv等库 使用SVM对字体进行分类 由以下步骤组成 1 使用Open
  • cd命令、pwd命令和环境变量PWD、OLDPWD的关联

    1 cd命令 cd命令这里不多介绍 cd 命令是返回上次所在的目录 2 PWD和OLDPWD环境变量 dai ubuntu env PWD home dai OLDPWD dai ubuntu 3 关联 1 当你输入 cd 命令返回上次的目
  • R语言之匹配篇

    2019独角兽企业重金招聘Python工程师标准 gt gt gt match match函数的声明如下 match x table nomatch NA integer incomparables NULL x 向量 要匹配的值 tabl
  • 深入MTK平台bootloader启动之【 Pre-loader -> Lk】分析笔记

    1 bootloader到kernel启动总逻辑流程图 ARM架构中 EL0 EL1是必须实现 EL2 EL3是选配 ELx跟层级对应关系 EL0 app EL1 Linux kernel lk EL2 hypervisor 虚拟化 EL3
  • Codeforces Round #589 (Div. 2)【数学 + 构造】

    A题 Distinct Digits 因为数的大小最长也就是5位 所以直接暴力求解即可 复杂度O 5 N include
  • C\C++ standard lib

    link
  • vue.js 解决空格报错!!!

    当我们初入vue js的时候 使用cli脚手架快速创建项目的时候 如果语法格式错误 这里主要指的是 空格多少引起的问题 找到 webpack base config js文件注释掉下面的东西 var path require path va
  • LeetCode 82. 删除排序链表中的重复元素 II

    题目链接 82 删除排序链表中的重复元素 II 设置虚拟头结点dummy不用考虑边界情况 p指针指向的是上一个没有重复的元素的位置 初始位置是dummy q从p gt next开始 一直走到第一个与q gt next不同元素的位置 删除中间
  • 经典目标检测算法—背景差分法、帧差法和三帧差法

    一 实验目的与要求 1 熟悉经典目标检测算法的原理 2 使用MATLAB语言编程实现背景差分法 帧差法和三帧差法 3 比较背景差分法 帧差法和三帧差法的特点 并了解该算法的应用条件 二 实验环境 Windows matlab 三 实验内容和
  • phpspreadsheet excel导入导出

    单个sheet页Excel2003版最大行数是65536行 Excel2007开始的版本最大行数是1048576行 Excel2003的最大列数是256列 2007以上版本是16384列 xlswriter xlswriter PHP 高性
  • Bean的四种注入方式

    1 set方法注入 2 构造器注入 3 静态工厂注入 4 实例工厂注入 我使用下面两个类来进行注入的演示 这两个类分别是User和Car类 Car类 public class Car 只包含基本数据类型的属性 private int spe
  • 内存管理篇 (一):Go语言之逃逸

    本篇做为Go语言内存管理的第一篇文章 会从下面几个方向来讲述逃逸 1 什么是逃逸 2 为什么需要逃逸 3 逃逸是怎么实现的 一 什么是逃逸 在开始讲逃逸之前 我们先看一下 下面的两个例子 例子1 stack go的fun 返回的就是一个in
  • 转载:浅谈批处理获取管理员运行权限的几种方法

    很多用了Win10版本系统的人都会发现 Windows对程序的运行权限是控制得更加严格了 即使你将UAC控制放至最低 如果没有特别赋予外来程序管理员运行权限的话 很多程序都会运行出错 包括很多用于系统维护的批处理程序由于运行权限不够都会导致
  • linux系统查看命令

    系统 uname a 查看内核 操作系统 CPU信息 head n 1 etc issue 查看操作系统版本 cat proc cpuinfo 查看CPU信息 hostname 查看计算机名 lspci tv 列出所有PCI设备 lsusb
  • Java弱引用(WeakReference)的理解与使用

    在Java里 当一个对象被创建时 它被放在内存堆里 当GC运行的时候 如果发现没有任何引用指向该对象 该对象就会被回收以腾出内存空间 或者换句话说 一个对象被回收 必须满足两个条件 1 没有任何引用指向它 2 GC被运行 Java对于简单的
  • Nacos Client2.2.9源码启动问题

    Nacos Client2 2 9源码启动问题 1 开启服务端 源码启动 推荐使用稳定版本作为 服务端 我是用了最新的2 2 1的nacos版本处理了一些问题 现在启动成功 nacos首页 http 192 168 3 111 8848 n
  • 分布式微电网能源交易算法matlab源代码孤岛微电网之间的能源交易问题,提出了一种分布式算法

    分布式微电网能源交易算法matlab源代码 代码按照高水平文章复现 保证正确 孤岛微电网之间的能源交易问题 提出了一种分布式算法 这个问题由几个通过任意拓扑交换能量流的岛屿微网格组成 提出了一种基于次梯度的开销最小化算法 该算法在实际迭代次
  • flutter报错[!] Android toolchain - develop for Android devices (Android SDK version 29.0.3) X Andr

    Flutter官网 问题 出现以下报错 说许可未知 解决方法 1 选择tools gt SDK Manager gt 2 SDK Platforms tab gt Android 9 0 Pie 3 安装 4 选择29 0 3下载重启And
  • 时序预测

    时序预测 MATLAB实现Hamilton滤波AR时间序列预测 目录 时序预测 MATLAB实现Hamilton滤波AR时间序列预测 预测效果 基本介绍 程序设计 参考资料 预测效果 基本介绍 预测在很大程度上取决于适合周期的模型和所采用的
  • flutter 生命周期

    生命周期似乎已经成为前端框架的标配了 然后在flutter中依然有生命周期这个概念 flutter是一个组件加载到卸载的整个周期 不同的生命周期内可以做的事情都是不一样 相信使用过react vue的小伙伴应该都清楚 在更新组件的时候在相应