生命周期似乎已经成为前端框架的标配了,然后在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() {} 组件被卸载后触发,用于监听组件卸载后去处理清理等操作,调用次数1次
reassemble() {}此回调是专门为了开发调试而提供的,在热重载(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;
}
}
}