Flutter的生命周期
Posted 小图包
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter的生命周期相关的知识,希望对你有一定的参考价值。
生命周期是一个从创建到销毁的过程,Flutter生命周期分为两部分:
1.Widget的生命周期
2.APP的生命周期
我们先看Widget的生命周期
一、Widget的生命周期
1.StatelessWidget
对于StatelessWidget来说,生命周期只有build过程。build是用来创建Widget的,在每次页面刷新时会调用build。
2.StatefulWidget
StatefulWidget的生命周期依次为:
initState:当Widget第一次插入到Widget树时会被调用,对于每一个State对象,这个方法只会调用一次。所以,通常在该回调中做一些一次性的操作,如一些初始化操作。(注意:不能在该回调中调用BuildContext.inheritFromWidgetOfExactType(该方法用于在Widget树上获取离当前widget最近的一个父级InheritFromWidget),原因是在初始化完成后,Widget树中的InheritFromWidget也可能会发生变化,所以正确的做法应该在在build()方法或didChangeDependencies()中调用它。)
didChangeDependencies():当State对象的依赖发生变化时会被调用;
这个方法在两种情况下会调用:
情况一:调用initState会调用;
情况二:从其他对象中依赖一些数据发生改变时,比如前面我们提到的InheritedWidget;
build:它主要是用于构建Widget子树
reassemble:此回调是专门为了开发调试而提供的,在热重载(hot reload)时会被调用,此回调在Release模式下永远不会被调用。
didUpdateWidget:在widget重新构建时,Flutter framework会调用Widget.canUpdate来检测Widget树中同一位置的新旧节点,然后决定是否需要更新,如果Widget.canUpdate返回true则会调用此回调。正如之前所述,Widget.canUpdate会在新旧widget的key和runtimeType同时相等时会返回true,也就是说在在新旧widget的key和runtimeType同时相等时didUpdateWidget()就会被调用。
deactivate:当State对象从树中被移除时,会调用此回调。在一些场景下,Flutter framework会将State对象重新插到树中,如包含此State对象的子树在树的一个位置移动到另一个位置时(可以通过GlobalKey来实现)。如果移除后没有重新插入到树中则紧接着会调用dispose()方法。
dispose:当State对象从树中被永久移除时调用;通常在此回调中释放资源。
生命周期图如下
示例如下
class Life extends StatefulWidget {
@override
_TestLifeState createState() => _TestLifeState();
}
class _TestLifeState extends State<Life> with WidgetsBindingObserver {
String title = "点击父组件";
@override
void initState() {
// TODO: implement initState
super.initState();
print('page1--initState');
WidgetsBinding.instance.addObserver(this);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
print(state.toString());
}
@override
void didChangeDependencies() {
print('test-page1--didChangeDependencies');
super.didChangeDependencies();
}
@override
void didUpdateWidget(Life oldWidget) {
print('test-page1--didUpdateWidget');
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
print('test-page1--build');
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text("生命周期示例"),
),
body: Column(
children: <Widget>[
GestureDetector(
child: new Text(title ?? ""),
onTap: () {
setState(() {
title = "父组件变化了";
});
},
),
Container(
width: 100,
height: 50,
child: Column (children: [
],),
),
ChildStatefulWidget(),
FlatButton(
color: Colors.grey,
onPressed: () {
Navigator.of(context)
.push(new MaterialPageRoute(builder: (BuildContext c) {
return new TestLifeCyclePage2();
}));
},
child: Text("跳转页面")),
],
),
);
}
@override
void reassemble() {
// TODO: implement reassemble
super.reassemble();
print('test-page1--reassemble');
}
@override
void deactivate() {
// TODO: implement deactivate
super.deactivate();
print('test-page1--deactivate');
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
//WidgetsBinding.instance.addObserver(this);
print('test-page1--dispose');
}
}
class ChildStatefulWidget extends StatefulWidget {
@override
_ChildStatefulWidgetState createState() {
print("child--createState");
return _ChildStatefulWidgetState();
}
}
class _ChildStatefulWidgetState extends State<ChildStatefulWidget> {
String title = "点击子组件";
@override
Widget build(BuildContext context) {
print('child--build');
return GestureDetector(
child: new Text(title ?? ""),
onTap: () {
setState(() {
title = "子组件变化了";
});
},
);
}
@override
void initState() {
print('child--initState');
super.initState();
}
@override
void didChangeDependencies() {
print('child--didChangeDependencies');
super.didChangeDependencies();
}
@override
void didUpdateWidget(ChildStatefulWidget oldWidget) {
print('child--didUpdateWidget');
super.didUpdateWidget(oldWidget);
}
@override
void reassemble() {
print('child--reassemble');
super.reassemble();
}
@override
void deactivate() {
print('child--deactivate');
super.deactivate();
}
@override
void dispose() {
print('child--dispose');
super.dispose();
//WidgetsBinding.instance.addObserver(this);
}
}
class TestLifeCyclePage2 extends StatefulWidget {
@override
_Test2LifeCyclePageState createState(){
return new _Test2LifeCyclePageState();
}
@override
StatefulElement createElement() {
// TODO: implement createElement
// print("page2--createElement");
return super.createElement();
}
}
class _Test2LifeCyclePageState extends State<TestLifeCyclePage2> with WidgetsBindingObserver {
@override
void initState() {
// TODO: implement initState
super.initState();
print('test-page2---initState');
WidgetsBinding.instance.addObserver(this);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
print(state.toString());
}
@override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
print('test-page2---didChangeDependencies');
}
@override
void didUpdateWidget(TestLifeCyclePage2 oldWidget) {
// TODO: implement didUpdateWidget
super.didUpdateWidget(oldWidget);
print('test-page2---didUpdateWidget');
}
@override
Widget build(BuildContext context) {
print('page2---build');
// TODO: implement build
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text("生命周期示例2"),
),
);
}
@override
void reassemble() {
// TODO: implement reassemble
super.reassemble();
print('test-page2---reassemble');
}
@override
void deactivate() {
// TODO: implement deactivate
super.deactivate();
print('test-page2---deactivate');
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
//WidgetsBinding.instance.addObserver(this);
print('test-page2---dispose');
}
}
进入page1 生命周期
点击父组件setState的生命周期
点击子组件的生命周期
进入page2 的生命周期
退出page2 的生命周期
点击热重载按钮的生命周期
二、 App的生命周期
App的生命周期需要通过WidgetsBindingObserver的didChangeAppLifecycleState来获取,在initState中添加监听WidgetsBinding.instance.addObserver(this);
resumed:可见并能响应用户的输入
inactive:处在并不活动状态,无法处理用户响应
paused:不可见并不能响应用户的输入,但是在后台继续活动
app从前台退到后台的生命周期
app 从后台回到前台的生命周期
退出app的生命周期
以上是关于Flutter的生命周期的主要内容,如果未能解决你的问题,请参考以下文章