Flutter中的生命周期
最近在写Flutter的时候发现对Flutter生命周期的各个阶段比较模糊,现在想写点关于Flutter生命周期的内容,巩固一下自己。
Widget的生命周期
我是一名Android开发,Android的生命周期是指Activity的生命周期。那么Flutter的生命周期其实就是指Widget的生命周期,并且是通过state来体现的,Flutter的核心设计思想就是一切皆Widget。
App是一个特殊的Widget,因为除了要处理视图界面的生命周期,还需要处理App启动到后台到退出App等状态。
无论对于Widget还是App,Flutter框架都提供了相应的回调方法,下面分别介绍Widget和App这两个不同类型的生命周期
Widget(的State)的生命周期
从图中可以看出State的生命周期可以分为3个阶段:创建、更新和销毁。
创建
State创建初始化时会依次执行,构造方法、initState、didChangeDependencies和build,随后完成页面渲染。
1.构造方法是State生命周期的起点,Flutter会通过调用StatefulWidget.createState()来创建一个State。通过构造方法可以接收父Widget传递的初始化UI配置数据,来决定Widget最初的呈现效果。
2.initState会在State对象被插入视图树的时候调用。在State生命周期中只会调用一次,一般在这里做一些初始化工作,比如为状态变量设置默认值等。
3.didChangeDependencies是专门处理State对象依赖关系变化,会在initState调用结束后执行。
4.build构建视图。在build中,我们根据父Widget传递过来的初始化配置数据,以及state当前状态,创建一个Widget然后返回。
更新
State的状态更新主要由三个方法触发:setState、didChangeDependencies和didUpdateWidget。
1.setState:当状态发生变化时,我们可以通过这个方法通知Flutter重建UI
2.didChangeDependencies:State对象的依赖关系发生变化后,Flutter会回调这个方法,然后触发组件构建。例如系统语言或者应用主题改变时,系统会通知State执行该回调方法。
3.didUpdateWidget:当Widget配置发生变化时,比如父Widget状态发生变化时,热重载时,系统会调用这个函数。
这三个方法调用后都会触发Flutter销毁旧Widget,并调用build方法重建Widget。
销毁
销毁阶段Flutter会调用deactivate和dispose这两个方法,来移除或销毁组件。
1.deactivate:当组件的可见状态发生改变时,该函数会被调用。当页面切换时,由于State在视图树的相对位置发生了变化,需要暂时移除后再重新添加,重新触发组件构建,因此这个函数也会被调用。即跳转下一页面时,当前页面会调用deactivate和build,当前页面关闭时,当前页面也会调用deactivate和build。
2.dispose:当State被永久从视图树中移除时会调用该函数,一般在这个函数里进行资源释放、监听移除、环境清理等操作。
App生命周期
当app启动,切换到后台或者退出时,Flutter也提供了相应的方法回调。需要混入WidgetsBindingObserver类来实现这样的需求,看看这个类具体有哪些回调函数
abstract class WidgetsBindingObserver {
// 页面 pop
Future<bool> didPopRoute() => Future<bool>.value(false);
// 页面 push
Future<bool> didPushRoute(String route) => Future<bool>.value(false);
// 系统窗口相关改变回调,如旋转
void didChangeMetrics() { }
// 文本缩放系数变化
void didChangeTextScaleFactor() { }
// 系统亮度变化
void didChangePlatformBrightness() { }
// 本地化语言变化
void didChangeLocales(List<Locale> locale) { }
//App 生命周期变化
void didChangeAppLifecycleState(AppLifecycleState state) { }
// 内存警告回调
void didHaveMemoryPressure() { }
//Accessibility 相关特性回调
void didChangeAccessibilityFeatures() {}
}
通过给WidgetsBinding的单例对象设置监听器,就可以监听这些回调方法。现在主要看App生命周期回调。
didChangeAppLifecycleState 回调函数中,有一个参数类型为AppLifecycleState的枚举类,这个类是Flutter对App生命周期状态的封装。常用的状态有resumed、inactive和paused这三个。
1.resumed:可见的,并能响应用户的输入。
2.inactive: 处在不活动状态,无法处理用户响应。
3.paused: 不可见并不能响应用户的输入,但是在后台继续活动中。
下面写个例子
class _LifecycleDemoState extends State<MyHomePage> with WidgetsBindingObserver{
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);// 注册监听器
}
@override
void dispose(){
super.dispose();
WidgetsBinding.instance.removeObserver(this);// 移除监听器
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
print("$state");
if (state == AppLifecycleState.resumed) {
//do sth
}else if(state == AppLifecycleState.paused) {
}
}
}
总结
上面是我对State和App的生命周期理解,我觉得对生命周期能够深入学习理解,这样写的程序会更流畅与清晰,所以了解Flutter的生命周期还是很有必要的。