赞
踩
一、生命周期阶段 flutter生命周期大体上可以分为三个阶段:初始化、状态变化、销毁。 1、初始化阶段 对应执行构造方法和initState时候 2、状态变化阶段 开新的widget或者调用setState方法的时候 3、销毁阶段 deactivate 和 dispose 二、生命周期阶段执行的函数 1、initState 调用次数:1次 插入渲染树时调用,只调用一次,widget创建执行的第一个方法,这里可以做一些初始化工作,比如初始化State的变量。 2、didChangeDependencies 调用次数:多次 初始化时,在initState()之后立刻调用 当依赖的InheritedWidget rebuild,会触发此接口被调用 实测在组件可见状态变化的时候会调用 3、build 调用次数:多次 初始化之后开始绘制界面 setState触发的时候会 4、didUpdateWidget 调用次数:多次 组件状态改变时候调用 5、deactivate 当State对象从树中被移除时,会调用此回调,会在dispose之前调用。 页面销毁的时候会依次执行:deactivate > dispose 6、dispose 调用次数:1次 当State对象从树中被永久移除时调用;通常在此回调中释放资源。 7、reassemble 在热重载(hot reload)时会被调用,此回调在Release模式下永远不会被调用 三、App生命周期 通过WidgetsBindingObserver的didChangeAppLifecycleState 来获取。通过该接口可以获取是生命周期在AppLifecycleState类中。 1、resumed 可见并能响应用户的输入,同安卓的onResume 2、inactive 处在并不活动状态,无法处理用户响应,同安卓的onPause 3、paused 不可见并不能响应用户的输入,但是在后台继续活动中,同安卓的onStop 下面是生命周期: 初次打开widget时,不执行AppLifecycleState的回调; 按home键或Power键, AppLifecycleState inactive---->AppLifecycleState pause 从后台到前台:AppLifecycleState inactive--->ApplifecycleState resumed back键退出应用: AppLifecycleState inactive--->AppLifecycleState paused ———————————————— 版权声明:本文为CSDN博主「一杯清泉」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/yoonerloop/article/details/121003373
Flutter 中的生命周期,包含以下几个阶段: createState ,该函数为 StatefulWidget 中创建 State 的方法,当 StatefulWidget 被调用时会立即执行 createState 。 initState ,该函数为 State 初始化调用,因此可以在此期间执行 State 各变量的初始赋值,同时也可以在此期间与服务端交互,获取服务端数据后调用 setState 来设置 State。 didChangeDependencies ,该函数是在该组件依赖的 State 发生变化时,这里说的 State 为全局 State ,例如语言或者主题等,类似于前端 Redux 存储的 State 。 build ,主要是返回需要渲染的 Widget ,由于 build 会被调用多次,因此在该函数中只能做返回 Widget 相关逻辑,避免因为执行多次导致状态异常。 reassemble ,主要是提供开发阶段使用,在 debug 模式下,每次热重载都会调用该函数,因此在 debug 阶段可以在此期间增加一些 debug 代码,来检查代码问题。 didUpdateWidget ,该函数主要是在组件重新构建,比如说热重载,父组件发生 build 的情况下,子组件该方法才会被调用,其次该方法调用之后一定会再调用本组件中的 build 方法。 deactivate ,在组件被移除节点后会被调用,如果该组件被移除节点,然后未被插入到其他节点时,则会继续调用 dispose 永久移除。 dispose ,永久移除组件,并释放组件资源。 整个过程分为四个阶段: 初始化阶段,包括两个生命周期函数 createState 和 initState; 组件创建阶段,也可以称组件出生阶段,包括 didChangeDependencies 和 build; 触发组件多次 build ,这个阶段有可能是因为 didChangeDependencies、setState 或者 didUpdateWidget 而引发的组件重新 build ,在组件运行过程中会多次被触发,这也是优化过程中需要着重需要注意的点; 最后是组件销毁阶段,deactivate 和 dispose。 import 'package:flutter/material.dart'; /// 创建有状态测试组件 class TestStatefulWidget extends StatefulWidget { @override createState() { print('create state'); return TestState(); } } /// 创建状态管理类,继承状态测试组件 class TestState extends State<TestStatefulWidget> { /// 定义 state [count] 计算器 int count = 1; /// 定义 state [name] 为当前描述字符串 String name = 'test'; @override initState() { print('init state'); super.initState(); } @override didChangeDependencies() { print('did change dependencies'); super.didChangeDependencies(); } @override didUpdateWidget(TestStatefulWidget oldWidget) { count++; print('did update widget'); super.didUpdateWidget(oldWidget); } @override deactivate() { print('deactivate'); super.deactivate(); } @override dispose() { print('dispose'); super.dispose(); } @override reassemble(){ print('reassemble'); super.reassemble(); } /// 修改 state name void changeName() { setState(() { print('set state'); this.name = 'flutter'; }); } @override Widget build(BuildContext context) { print('build'); return Column( children: <Widget>[ FlatButton( child: Text('$name $count'), // 使用 Text 组件显示描述字符和当前计算 onPressed:()=> this.changeName(), // 点击触发修改描述字符 state name ) ], ); } } 在 main.dart 中加载该组件 import 'package:flutter/material.dart'; import 'package:two_you_friend/pages/test_stateful_widget.dart'; /// APP 核心入口文件 void main() => runApp(MyApp()); /// MyApp 核心入口界面 class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Two You', // APP 名字 theme: ThemeData( primarySwatch: Colors.blue, // APP 主题 ), home: Scaffold( appBar: AppBar( title: Text('Two You'), // 页面名字 ), body: Center( child: TestStatefulWidget(), ) )); } } 作者:丘山Ivan 链接:https://www.jianshu.com/p/0f8a4b541ea4 来源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Flutter使用didChangeAppLifecycleState遇到的问题 伊路顺峰 2021.04.12 18:07:38 字数 339 阅读 680 项目中有个简单的需求,用户退出程序(挂起到后台,没有杀死程序)再回到HomePage页面的时候需要调一个刷新数据的接口,就用了Flutter 声明周期监听,这个也比较简单:混入一个WidgetsBindingObserver类,在initState 中添加监听WidgetsBinding.instance.addObserver(this); 然后重写didChangeAppLifecycleState方法判断状态 @override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); ///回到主页面时刷新数据 if (state == AppLifecycleState.resumed) { refreshData(); } } 后来遇到一个问题,在项目中还用到了扫描二维码的三方插件:barcode_scan_fix: ^1.0.2,当扫码完成后发现调用了refreshData()方法,后来打印日志才发现手机进入扫码页面的时候AppLifecycleState为paused,到扫码完成后AppLifecycleState为resumed,然后就调用了HomePage页面的刷新数据方法。 我当时解决问题的方案借助了路由监听RouteAware,判断当前页面的入栈和出栈,定义一个变量,在push到下一个页面和返回到当前页面的时候改变这个值, bool _inCurrentPage = true;///是否在当前页面 在HomePage混入RouteAware类,在MaterialApp添加navigatorObservers属性,我这里用把它放到了一个全局变量CommonData中 image.png image.png 然后在HomePageState 中重写两个方法: //由子页面 返回时刷新 @override void didPopNext() { _inCurrentPage = true; } //进入子页面 @override void didPushNext() { _inCurrentPage = false; super.didPushNext(); } 最后在声明周期中加上这个判断: //由后台返回主屏幕 刷新数据 @override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); if (state == AppLifecycleState.resumed && _inCurrentPage) { refreshPage(); } }
1.class ShakeGameState extends State<ShakeGame> with WidgetsBindingObserver
2. @override
void initState() {
WidgetsBinding.instance!.addObserver(this);
super.initState();
}
3. @override
void dispose() {
super.dispose();
WidgetsBinding.instance!.removeObserver(this);
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。