生命周期似乎已经成为前端框架的标配了,然后在flutter中依然有生命周期这个概念。
flutter是一个组件加载到卸载的整个周期,不同的生命周期内可以做的事情都是不一样,相信使用过react,vue的小伙伴应该都清楚,在更新组件的时候在相应生命周期相业务逻辑、初始化页面的时候做一些数据处理等等。
废话不多说,先上flutter的生命周期图:
初始化时会依次执行:构造函数 > 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() {} 组件被卸载后触发,用于监听组件卸载后去处理清理等操作,调用次数1次
reassemble() {}此回调是专门为了开发调试而提供的,在热重载(hot reload)时会被调用,此回调在Release模式下永远不会被调用
didChangeAppLifecycleState(AppLifecycleState state) {}获取App的生命周期,此生命周期内可以获取用户不同状态的生命周期,此方法必须继承
AppLifecycleState.resumed可见并能响应用户的输入
AppLifecycleState.inactive处在并不活动状态,无法处理用户响应
AppLifecycleState.paused不可见并不能响应用户的输入,但是在后台继续活动中
代码打印这些方法在何时执行(测试生命周期)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
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 才能获取到的,具体如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// ...省略 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; } } } |