简介
Flutter 跟 Android 的 Activity、iOS 的 ViewController 一样都拥有自己的生命周期。在 Flutter 中几乎所有的对象都是一个 Widget,其中 Widget 又分为 StatelessWidget(即:无状态的 Widget) 和 StatefulWidget (即:有状态的 Widget),这里所说的 Flutter 的生命周期其实就是讲 StatefulWidget 的生命周期,它存在于 framework.dart
的 State 类中。
代码实测
写个有状态类并混入 WidgetsBindingObserver 配合监听特殊状态及其一个按钮,调用 setState, 给生命周期的方法新增打印:
代码语言:javascript复制import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: '生命周期',
home: new LiftCycle(),
);
}
}
class LiftCycle extends StatefulWidget {
@override
_LiftCycleState createState() => _LiftCycleState();
}
class _LiftCycleState extends State<LiftCycle> with WidgetsBindingObserver {
int count = 0;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
print('初始化 initState');
}
@override
void didUpdateWidget(LiftCycle oldWidget) {
super.didUpdateWidget(oldWidget);
print('组件更新 didUpdateWidget');
}
@override
void reassemble() {
super.reassemble();
print('重新安装 reassemble');
}
@override
void deactivate() {
super.deactivate();
print('停用 deactivate');
}
@override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);
print('销毁 dispose');
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
print('特殊状态 state:$state');
}
@override
void setState(fn) {
super.setState(fn);
print('状态刷新 setState');
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text('生命周期')),
body: new Center(
child: new FlatButton(
onPressed: () => setState(() => count ),
child: new Text('$count'),
),
),
);
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
print('依赖改变 didChangeDependencies');
}
}
然后我们现在来看看打印流程,正常打开 App 什么都不操作,就打印了:
代码语言:javascript复制I/flutter (15867): 初始化 initState
I/flutter (15867): 依赖改变 didChangeDependencies
I/flutter (15867): 重新安装 reassemble
I/flutter (15867): 组件更新 didUpdateWidget
热重载打印:
代码语言:javascript复制I/flutter (16141): 重新安装 reassemble
I/flutter (16141): 组件更新 didUpdateWidget
Reloaded 0 of 468 libraries in 186ms.
点击按钮打印:
代码语言:javascript复制I/flutter (16141): 状态刷新 setState
// count也 1了,说明重新调用过build。
流程图
构造函数:
构造函数不属于生命周期,必然是要第一个调用的,也就是调用前 State 的 widget 属性为空。
initState 初始化:
当此对象插入树中时调用,框架会调用一次此方法并不会再次重复执行, 如果 State 的 build 方法依赖于本身可以更改状态的对象,例如:ChangeNotifier 或 Stream, 或者某些其他可以订阅的对象接收通知,可以在此方法订阅,但记得去 dispose 取消订阅。
didChangeDependencies 依赖改变:
顾名思义,依赖项更改时调用,但也会在 initState 之后调用, 在这个方法调用 BuildContext.inheritFromWidgetOfExactType
是安全的。
build 构建:
会在以下场景调用:
- initState() 之后。
- didUpdateWidget() 之后。
- setState() 之后。
- didChangeDependencies() 之后。
- State 对象从树中一个位置移除后会调用 deactivate,然后又重新插入到树的其它位置之后。
reassemble 重新安装:
专门为了开发调试而提供的,在热重载 hot reload
时会被调用,此回调在 Release 模式下永远不会被调用。
didUpdateWidget 组件更新:
当组件的状态改变的时候就会调用 didUpdateWidget(),比如调用了 setState(), 在 widget 重新构建时,Flutter framework 会调用 Widget.canUpdate
来检测 Widget 树中同一位置的新旧节点, 然后决定是否需要更新,如果 Widget.canUpdate
返回 true 则会调用此回调。正如之前所述,Widget.canUpdate
会在 新旧 widget 的 key 和 runtimeType 同时相等时会返回 true,也就是说在新旧 widget 的 key 和 runtimeType 同时相等时 didUpdateWidget() 就会被调用。
deactivate 暂停:
State 对象从树中被移除时(在 dispose 之前),会调用这个函数来将对象暂停。
dispose 销毁:
当 State 对象被销毁时调用,通常在此回调中释放资源和移除监听。
特殊状态
我们自定义的 State 类混入了 WidgetsBindingObserver,所以可以使用他的暂停和恢复。
初始化:
代码语言:javascript复制@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this); // 在这初始化了
print('初始化 initState');
}
销毁:
代码语言:javascript复制@override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this); // 在这销毁
print('销毁 dispose');
}
使用:
代码语言:javascript复制@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
print('特殊状态 state:$state');
}
这个 didChangeAppLifecycleState 是 WidgetsBindingObserver 类的一个方法,可以用来判断当前的状态是在前台还是后台。
这个方法接收一个AppLifecycleState类型的枚举:
枚举值 | 含义 |
---|---|
resumed | 程序可见,并响应用户输入。 |
inactive | 处于非活动状态,未收到用户输入。 |
paused | 程序当前不可见,不响应用户输入,并且在后台运行。 |
suspending | 程序将暂时暂停。 |
AppLifecycleState 实测
当App返回到桌面或者其他不可见状态,但并未结束:
代码语言:javascript复制I/flutter ( 2428): 特殊状态 state:AppLifecycleState.inactive
I/flutter ( 2428): 特殊状态 state:AppLifecycleState.paused
当App回到可见状态:
代码语言:javascript复制I/flutter ( 2428): 特殊状态 state:AppLifecycleState.inactive
I/flutter ( 2428): 特殊状态 state:AppLifecycleState.resumed
流程图: