生命周期在 UI 绘制中的重要作用。Flutter 中也存在生命周期,它的回调方法都体现在 State 中,源码参考。
Flutter 生命周期
页面的生命周期
以 StatefulWidget 为例,来看一下 Flutter 页面的生命周期是怎样的。 Widget 的生命周期大体上可以分为三个阶段:
1. 初始化
createState
//这个方法是必须重写的
@override
_LifecycleWidgetState createState() => _LifecycleWidgetState();
当构建一个 StatefulWidget 时这个方法会被首先调用,而且这个方法是必须要重写的。
initState
@override
void initState() {
super.initState();
}
这个方法调用发生在 createState
之后,是除构造方法之外,调用的第一个方法,它的作用类似于 Android 的 onCreate()
和 iOS 的 viewDidLoad()
。这个方法中通常会做一些初始化工作,比如 channel 的初始化、监听器的初始化等。 与 dispose()
相对应。
2. 状态改变
-
didChangeDependencies
@override void didChangeDependencies() { super.didChangeDependencies(); }
这个方法要求必须要调用父类的方法
super.didChangeDependencies
,当依赖的 State 的对象改变时会调用。- 在第一次构建 Widget 时,在
initState()
之后立即调用此方法。 - 如果 StatefulWidgets 依赖于 InhertedWidget,那么当当前 State 所依赖 InheritedWidget 中的变量改变时会再次调用它。
- 在第一次构建 Widget 时,在
-
build
@override
Widget build(BuildContext context) {
return Container();
}
是一个必须实现的方法,在这里实现要呈现的页面内容。它会在didChangeDependencies()
之后立即调用,另外当调用 setState()
后也会再次调用这个方法
didUpdateWidget
@override
void didUpdateWidget(covariant LifecycleWidget oldWidget) {
super.didUpdateWidget(oldWidget);
}
调用 setState
将 Widget 的状态改变时 didUpdateWidget
会被调用,Flutter 会创建一个新的 Widget 来绑定这个 State,并在这个方法中传递旧的 Widget ,因此如果想比对新旧 Widget 并且对 State 做一些调整,可以使用它。
另外如果某些 Widget 上涉及到 controller 的变更,那么一定要在这个回调方法中移除旧的 controller 并创建新的 controller 监听。
3. 销毁
-
deactivate
@override void deactivate() { super.deactivate(); }
这个方法不常用,它会在组件被移除时调用,而且是在
dispose
调用之前 -
dispose
@override void dispose() { super.dispose(); }
与
initState()
对应。组件销毁时调用,通常该方法中执行一些释放资源的工作,如监听器的移除,channel 的销毁等,相当于 iOS 的
dealloc
。方法参考
App 的生命周期
App 中会有比如从前台切入到后台再从后台切回到前台的场景, Flutter 中我们该如何处理这些场景?对于 App 级别的生命周期与上述 Widget 生命周期相比,稍有不同。
如果想监听 App 的生命周期需要使用 WidgetsBinding
来监听 WidgetsBindingObserver
,WidgetsBindingObserver
是一个 Widgets 绑定观察器,通过它来监听应用的生命周期,使用混入的方式绑定观察器,并且需要在 dispose
回调方法中移除这个监听。
重写 didChangeAppLifecycleState
,当生命周期发生变化的时候会回调这个方法,
class _LifecycleAPPState extends State<LifecycleAPP>
with WidgetsBindingObserver {
@override
void initState() {
//添加监听
WidgetsBinding.instance!.addObserver(this);
super.initState();
}
@override
Widget build(BuildContext context) {
return Container();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
print(state);
}
@override
void dispose() {
// 移除监听
WidgetsBinding.instance!.removeObserver(this);
super.dispose();
}
}
Flutter 封装了一个枚举 AppLifecycleState
来描述 APP 的生命周期:
enum AppLifecycleState {
resumed, // 进入前台
inactive, // app 处于非活跃状态,并且未接收到用户输入的时候调用。比如接听来电
paused,// 进入后台
detached, // app 仍寄存在Flutter引擎上,但与原生平台分离
}
我们可以拿到这个 state 在 didChangeAppLifecycleState()
来做一些我们需要的处理逻辑。