Flutter Widget 生命周期

作为一名客户端开发,无论是Android/IOS,生命周期的概念深入骨髓,那么一个优秀的跨平台方案,Flutter Widget是怎么处理生命周期的呢,接下来就让我们一起了解一下,以图镇楼。

Flutter Widget 生命周期

从图中我们可以看到Flutter Widget的生命周期分为两部分:一部分是Widget本身的周期,跟随Widget在layer tree的状态而改变,另一部分则是依赖于Native Application的生命周期。

实践·验证

接下来我们通过实践来验证一下真实的生命周期是否如图中所示,以Android为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
@override
void initState() {
// TODO: implement initState
super.initState();
WidgetsBinding.instance.addObserver(this);
print('initState');
}

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.inactive:
print('AppLifecycleState.inactive');
break;
case AppLifecycleState.paused:
print('AppLifecycleState.paused');
break;
case AppLifecycleState.resumed:
print('AppLifecycleState.resumed');
break;
case AppLifecycleState.detached:
print('AppLifecycleState.detached');
break;
}

super.didChangeAppLifecycleState(state);
}

@override
void didChangeDependencies() {
super.didChangeDependencies();
print('didChangeDependencies');
}

@override
void didUpdateWidget(MyHomePage oldWidget) {
super.didUpdateWidget(oldWidget);
print('didUpdateWidget');
}

@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');
}));
},
)),
);
}

@override
void reassemble() {
super.reassemble();
print('reassemble');
}

@override
void deactivate() {
super.deactivate();
print('deactivate');
}

@override
void dispose() {
super.dispose();
WidgetsBinding.instance.addObserver(this);
print('dispose');
}
}

1、创建一个wedget到显示 打印结果如下

1
2
3
01-15 14:06:44.751 19005-19025/com.example.flutterapp I/flutter: initState
01-15 14:06:44.751 19005-19025/com.example.flutterapp I/flutter: didChangeDependencies
01-15 14:06:44.752 19005-19025/com.example.flutterapp I/flutter: build

2、跳转到其他页面执行

1
2
01-15 14:08:40.956 19005-19561/com.example.flutterapp I/flutter: deactivate
01-15 14:08:40.970 19005-19561/com.example.flutterapp I/flutter: dispose

3、点击热重载按钮

1
2
3
01-15 14:09:55.467 19005-19561/com.example.flutterapp I/flutter: reassemble
01-15 14:09:55.476 19005-19561/com.example.flutterapp I/flutter: didUpdateWidget
01-15 14:09:55.476 19005-19561/com.example.flutterapp I/flutter: build

4、app由显示切换到后台(home状态)

1
2
01-15 14:11:10.062 19005-19561/com.example.flutterapp I/flutter: AppLifecycleState.inactive
01-15 14:11:10.524 19005-19561/com.example.flutterapp I/flutter: AppLifecycleState.paused

5、app由后台切回前台

1
2
01-15 14:11:54.836 19005-19561/com.example.flutterapp I/flutter: AppLifecycleState.inactive
01-15 14:11:54.837 19005-19561/com.example.flutterapp I/flutter: AppLifecycleState.resumed
  • initState:widget创建执行的第一个方法,可以再里面初始化一些数据,以及绑定控制器;
  • didChangeDependencies:当State对象的依赖发生变化时会被调用;例如:在之前build() 中包含了一个InheritedWidget,然后在之后的build() 中InheritedWidget发生了变化,那么此时InheritedWidget的子widget的didChangeDependencies()回调都会被调用。InheritedWidget这个widget可以由父控件向子控件共享数据,案例可以参考 scoped_model开源库。

  • build :它主要是用于构建Widget子树的。

  • reassemble:此回调是专门为了开发调试而提供的,在热重载(hot reload)时会被调用,此回调在Release模式下永远不会被调用。

  • didUpdateWidget:当树rebuid的时候会调用该方法。

  • deactivate:当State对象从树中被移除时,会调用此回调。

  • dispose():当State对象从树中被永久移除时调用;通常在此回调中释放资源。

代码中的didChangeAppLifecycleState方法需要复写WidgetsBindingObserver这个抽象类

参考