Flutter 从浅入深理解生命周期
为什么需要了解生命周期?
在Android开发的时候,App、Activity、Fragment是有生命周期的,熟悉了生命周期之后我们就可以在适当的时机做适当操作。比如在Android中在执行到OnDestory生命周期是需要资源释放。
在Flutter中也是有生命周期的,主要有两个:
Widget的生命周期App的生命周期
Widget 的生命周期
上篇文章
Flutter 从浅入深理解 StatefulWidget 和 StatelessWidget
我们介绍了Widget主要有两类StatelessWidget 和 StatefulWidget
那么先来看StatelessWidget的生命周期,从源码中可以看到StatelessWidget的生命周期只有一个build方法。
再来看StatefulWidget的生命周期,StatefulWidget是有状态的Widget,并依赖于State。其生命周期如下图:
图片来源:梁飞宇 -【Flutter学习】之 Flutter 的生命周期
从图中可以看出生命周期可以分为三部分:创建、更新、销毁
下面我们通过AndroidStudio在各个生命周期方法中打印日志,来查看一些场景下Widget的生命周期方法调用。
页面创建
minePage页面的创建过程如下图
从打印的日志中可以看出widget创建走的生命周期和上图中的 第一部分:创建 是一致的。
页面跳转
此时点击跳转 loginPage 页面,两个页面的生命周期执行如下图:
从打印的日志可以看出,loginPage 执行了createState、constrictor、initState、didChangeDependencied、build生命周期之后,minePage 才执行deactivate、didChangeDependencies、didUpdateWidget、build 生命周期。
点击返回键
从loginPage页面返回上一个页面minePage,Widget的生命周期执行如下:
从打印的日志可以看出,minePage 执行deactivate、didChangeDependencies、didUpdateWidget、build 生命周期之后,loginPage 执行了deactivate生命周期之后,minePage 又执行了build 生命周期,loginPage 又执行了deactivate生命周期。
setState() 方法调用之后
从loginPage登录成功之后返回minePage并将用户名和头像使用setState()修改为网络数据。
此时的生命周期打印如下:
从打印的日志可以看出,在页面返回之后,也就是setState之后,minePage 生命周期执行了didChangeDependencies、didUpdateWidget、build 方法。
小结
| 生命周期方法 | 调用时机 | 执行次数 |
|---|---|---|
| createState | 创建State对象前 | 1 |
| constructor | 创建State对象时 | 1 |
| initState | 当State 对象插入视图树之后 | 1 |
| didChangeDepandencies | State 对象的依赖关系发生变化后 | >=1 |
| build | State 改动之后 | >=1 |
| setState | 需要刷新 UI 时 | >=1 |
| didUpdateWidget | 当 widget 配置发生变化时,如调用 setState 触发 | >=1 |
| deactivate | widget 不可见时 | >=1 |
| dispose | widget 被永久移除 | 1 |
App 的生命周期
上面我们了解了widget的生命周期之后,现在来了解监听App的生命周期。
在 Flutter 中,我们可以利用 WidgetsBindingObserver 类,
我们来看看 WidgetsBindingObserver 中具体有哪些回调函数:
通过查看WidgetsBindingObserver源码及参考Flutter核心技术与实战专栏,我们可以找到如下一些信息:
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() {}
}
我们可以看到didChangeAppLifecycleState是用于监听App 的生命周期变化
那么如何实现监听App的生命周期呢?
如何监听App的生命周期
// 使用 with WidgetsBindingObserver
class MinePageState extends State<MinePage> with WidgetsBindingObserver {
@override
void initState() {
super.initState();
//注册监听器
WidgetsBinding.instance.addObserver(this);
WidgetsBinding.instance.addPostFrameCallback((_){
// 只回调一次
print("单次Frame绘制回调");
});
WidgetsBinding.instance.addPersistentFrameCallback((_){
//每帧都回调
print("实时Frame绘制回调");
});
}
/// 重写方法,实现App生命周期监听
@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
print("$state");
if (state == AppLifecycleState.resumed) {
// resumed 状态
}
}
@override
void dispose() {
super.dispose();
//移除监听器
WidgetsBinding.instance.removeObserver(this);
}
}
App操作常见情景下生命周期方法调用
例如:灭、亮屏以及点击 Home 键再返回App,会执行如下生命周期
- resumed:可见的,并能响应用户的输入,如上图中的亮屏和从点击 home 键之后再启动 App 会调用。
- inactive:处在不活动状态,无法处理用户响应。
- paused:不可见并不能响应用户的输入,但是在后台继续活动中,如上图中的灭屏和点击 home 键之后会调用。
完~
更多推荐



所有评论(0)