什么是生命周期呢?
客戶端開發(fā):iOS開發(fā)中我們需要知道UIViewController從創(chuàng)建到銷毀的整個(gè)過程,Android開發(fā)中我們需要知道Activity從創(chuàng)建到銷毀的整個(gè)過程。以便在不同的生命周期方法中完成不同的操作;
前端開發(fā)中:Vue、React開發(fā)中組件也都有自己的生命周期,在不同的生命周期中我們可以做不同的操作;
Flutter小部件的生命周期:
StatelessWidget可以由父Widget直接傳入值,調(diào)用build方法來構(gòu)建,整個(gè)過程非常簡單;
而StatefulWidget需要通過State來管理其數(shù)據(jù),并且還要監(jiān)控狀態(tài)的改變決定是否重新build整個(gè)Widget;
所以,我們主要討論StatefulWidget的生命周期,也就是它從創(chuàng)建到銷毀的整個(gè)過程;
1.3.2. 生命周期的簡單版
在這個(gè)版本中,我講解那些常用的方法和回調(diào),下一個(gè)版本中我解釋一些比較復(fù)雜的方法和回調(diào)
那么StatefulWidget有哪些生命周期的回調(diào)呢?它們分別在什么情況下執(zhí)行呢?
在下圖中,灰色部分的內(nèi)容是Flutter內(nèi)部操作的,我們并不需要手動(dòng)去設(shè)置它們;
白色部分表示我們可以去監(jiān)聽到或者可以手動(dòng)調(diào)用的方法;
我們知道StatefulWidget本身由兩個(gè)類組成的:StatefulWidget和State,我們分開進(jìn)行分析
首先,執(zhí)行StatefulWidget中相關(guān)的方法:
1、執(zhí)行StatefulWidget的構(gòu)造函數(shù)(Constructor)來創(chuàng)建出StatefulWidget;
2、執(zhí)行StatefulWidget的createState方法,來創(chuàng)建一個(gè)維護(hù)StatefulWidget的State對(duì)象;
其次,調(diào)用createState創(chuàng)建State對(duì)象時(shí),執(zhí)行State類的相關(guān)方法:
1、執(zhí)行State類的構(gòu)造方法(Constructor)來創(chuàng)建State對(duì)象;
2、執(zhí)行initState,我們通常會(huì)在這個(gè)方法中執(zhí)行一些數(shù)據(jù)初始化的操作,或者也可能會(huì)發(fā)送網(wǎng)絡(luò)請(qǐng)求;
注意:這個(gè)方法是重寫父類的方法,必須調(diào)用super,因?yàn)楦割愔袝?huì)進(jìn)行一些其他操作;
并且如果你閱讀源碼,你會(huì)發(fā)現(xiàn)這里有一個(gè)注解(annotation):@mustCallSuper
3、執(zhí)行didChangeDependencies方法,這個(gè)方法在兩種情況下會(huì)調(diào)用
情況一:調(diào)用initState會(huì)調(diào)用;
情況二:從其他對(duì)象中依賴一些數(shù)據(jù)發(fā)生改變時(shí),比如前面我們提到的InheritedWidget(這個(gè)后面會(huì)講到);
4、Flutter執(zhí)行build方法,來看一下我們當(dāng)前的Widget需要渲染哪些Widget;
5、當(dāng)前的Widget不再使用時(shí),會(huì)調(diào)用dispose進(jìn)行銷毀;
6、手動(dòng)調(diào)用setState方法,會(huì)根據(jù)最新的狀態(tài)(數(shù)據(jù))來重新調(diào)用build方法,構(gòu)建對(duì)應(yīng)的Widgets;
7、執(zhí)行didUpdateWidget方法是在當(dāng)父Widget觸發(fā)重建(rebuild)時(shí),系統(tǒng)會(huì)調(diào)用didUpdateWidget方法;

/*
理解生命周期的函數(shù)能做什么以及意義?
1.初始化一些數(shù)據(jù)、變量、狀態(tài)
2.發(fā)送網(wǎng)絡(luò)請(qǐng)求
3.監(jiān)聽屬性變化
4.進(jìn)行一些事件的監(jiān)聽controller添加監(jiān)聽事件
5.管理內(nèi)存:一些定時(shí)器手動(dòng)進(jìn)行銷毀
*/
import 'package:flutter/material.dart';
main() {
runApp(MaterialApp(
home:KSJScaffold()
));
}
/*
StatelessWidget生命周期函數(shù)執(zhí)行過程?
flutter: 構(gòu)造函數(shù)被調(diào)用
flutter: build函數(shù)被調(diào)用
flutter: build函數(shù)被調(diào)用
*/
class KSJStatelessWidgetextends StatelessWidget {
final Stringmessage;
? KSJStatelessWidget(this.message) {
print('構(gòu)造函數(shù)被調(diào)用');
? }
@override
? Widgetbuild(BuildContext context) {
print('build函數(shù)被調(diào)用');
? ? return Container();
? }
}
/*
performing hot restart...
Syncing files to device iPhone X...
Restarted application in 2,941ms.
flutter: 開始:父節(jié)點(diǎn)發(fā)生改變或新建
flutter: 1.KSJApp的構(gòu)造函數(shù)被調(diào)用
flutter: 2.KSJApp的createState被調(diào)用
flutter: 3.KSJApp的_KSJAppState被調(diào)用
flutter: 4.KSJApp的initState被調(diào)用
flutter: 父節(jié)點(diǎn)build被調(diào)用=>didChangeDependencies
flutter: 5.KSJApp的build被調(diào)用
flutter: 開始:父節(jié)點(diǎn)發(fā)生改變或新建
flutter: 1.KSJApp的構(gòu)造函數(shù)被調(diào)用
flutter: KSJ的didUpdateWidget
flutter: 5.KSJApp的build被調(diào)用
flutter: 開始:父節(jié)點(diǎn)發(fā)生改變或新建
flutter: 1.KSJApp的構(gòu)造函數(shù)被調(diào)用
flutter: KSJ的didUpdateWidget
flutter: 5.KSJApp的build被調(diào)用
*/
class KSJScaffoldextends StatefulWidget {
@override
? _KSJScaffoldStatecreateState() =>_KSJScaffoldState();
}
class _KSJScaffoldStateextends State {
num_count =0;
? @override
? Widgetbuild(BuildContext context) {
print("開始:父節(jié)點(diǎn)發(fā)生改變或新建");
? ? return? Scaffold(
appBar:AppBar(title:Text('KSJ')),
? ? ? ? body:Column(
children: [
KSJApp("ksj"),
? ? ? ? ? ? RaisedButton(child:Text('+'), onPressed: (){
setState(() {
_count++;
? ? ? ? ? ? ? });
? ? ? ? ? ? }),
? ? ? ? ? ? Text('${this._count}')
],
? ? ? ? )
);
? }
}
class KSJAppextends StatefulWidget {
final Stringmessage;
? KSJApp(this.message) {
print('1.KSJApp的構(gòu)造函數(shù)被調(diào)用');
? }
@override
? _KSJAppStatecreateState() {
print('2.KSJApp的createState被調(diào)用');
? ? return _KSJAppState();
? }
}
class _KSJAppStateextends State {
num_counter =0;
? _KSJAppState(){
print('3.KSJApp的_KSJAppState被調(diào)用');
? }
@override
? void initState() {
// TODO: implement initState
? ? //? @mustCallSuper
? ? super.initState();
? ? print('4.KSJApp的initState被調(diào)用');
? }
// 數(shù)據(jù)改變依賴的時(shí)候會(huì)發(fā)生改變并調(diào)用
// 情況1:調(diào)用 initState會(huì)調(diào)用
// 情況2:從其他對(duì)象中依賴一些數(shù)據(jù)發(fā)生改變時(shí),比如前面我們提到的inheritedWidget(這個(gè)后面會(huì)講到)
? @override
? void didChangeDependencies() {
// TODO: implement didChangeDependencies
? ? super.didChangeDependencies();
? ? print('didChangeDependencies');
? }
@override
? void didUpdateWidget(KSJApp oldWidget) {
// TODO: implement didUpdateWidget
? ? super.didUpdateWidget(oldWidget);
? ? print('KSJ的didUpdateWidget');
? }
@override
? Widgetbuild(BuildContext context) {
print('5.KSJApp的build被調(diào)用');
? ? return Center(
child:Column(
children: [
Text('$_counter'),
? ? ? ? ? RaisedButton(child:Text("增加"), onPressed: (){
// set方法的調(diào)用會(huì)觸發(fā)build的方法的使用
? ? ? ? ? ? print('set方法的調(diào)用會(huì)觸發(fā)build的方法的調(diào)用');
? ? ? ? ? ? setState(() {
_counter++;
? ? ? ? ? ? });
? ? ? ? ? })
],
? ? ? ),
? ? );
? }
@override
? void dispose() {
// TODO: implement dispose
? ? print('6.KSJApp的dispose被調(diào)用');
? ? super.dispose();
? }
}
復(fù)制備份用:
/*
理解生命周期的函數(shù)能做什么以及意義?
1.初始化一些數(shù)據(jù)、變量、狀態(tài)
2.發(fā)送網(wǎng)絡(luò)請(qǐng)求
3.監(jiān)聽屬性變化
4.進(jìn)行一些事件的監(jiān)聽controller添加監(jiān)聽事件
5.管理內(nèi)存:一些定時(shí)器手動(dòng)進(jìn)行銷毀
*/
import 'package:flutter/material.dart';
main() {
runApp(MaterialApp(
home:KSJScaffold()
));
}
/*
StatelessWidget生命周期函數(shù)執(zhí)行過程?
flutter: 構(gòu)造函數(shù)被調(diào)用
flutter: build函數(shù)被調(diào)用
flutter: build函數(shù)被調(diào)用
*/
class KSJStatelessWidgetextends StatelessWidget {
final Stringmessage;
? KSJStatelessWidget(this.message) {
print('構(gòu)造函數(shù)被調(diào)用');
? }
@override
? Widgetbuild(BuildContext context) {
print('build函數(shù)被調(diào)用');
? ? return Container();
? }
}
/*
performing hot restart...
Syncing files to device iPhone X...
Restarted application in 2,941ms.
flutter: 開始:父節(jié)點(diǎn)發(fā)生改變或新建
flutter: 1.KSJApp的構(gòu)造函數(shù)被調(diào)用
flutter: 2.KSJApp的createState被調(diào)用
flutter: 3.KSJApp的_KSJAppState被調(diào)用
flutter: 4.KSJApp的initState被調(diào)用
flutter: 父節(jié)點(diǎn)build被調(diào)用=>didChangeDependencies
flutter: 5.KSJApp的build被調(diào)用
flutter: 開始:父節(jié)點(diǎn)發(fā)生改變或新建
flutter: 1.KSJApp的構(gòu)造函數(shù)被調(diào)用
flutter: KSJ的didUpdateWidget
flutter: 5.KSJApp的build被調(diào)用
flutter: 開始:父節(jié)點(diǎn)發(fā)生改變或新建
flutter: 1.KSJApp的構(gòu)造函數(shù)被調(diào)用
flutter: KSJ的didUpdateWidget
flutter: 5.KSJApp的build被調(diào)用
*/
class KSJScaffoldextends StatefulWidget {
@override
? _KSJScaffoldStatecreateState() =>_KSJScaffoldState();
}
class _KSJScaffoldStateextends State?{
num_count =0;
? @override
? Widgetbuild(BuildContext context) {
print("開始:父節(jié)點(diǎn)發(fā)生改變或新建");
? ? return? Scaffold(
appBar:AppBar(title:Text('KSJ')),
? ? ? ? body:Column(
children:?[
KSJApp("ksj"),
? ? ? ? ? ? RaisedButton(child:Text('+'), onPressed: (){
setState(() {
_count++;
? ? ? ? ? ? ? });
? ? ? ? ? ? }),
? ? ? ? ? ? Text('${this._count}')
],
? ? ? ? )
);
? }
}
class KSJAppextends StatefulWidget {
final Stringmessage;
? KSJApp(this.message) {
print('1.KSJApp的構(gòu)造函數(shù)被調(diào)用');
? }
@override
? _KSJAppStatecreateState() {
print('2.KSJApp的createState被調(diào)用');
? ? return _KSJAppState();
? }
}
class _KSJAppStateextends State?{
num_counter =0;
? _KSJAppState(){
print('3.KSJApp的_KSJAppState被調(diào)用');
? }
@override
? void initState() {
// TODO: implement initState
? ? //? @mustCallSuper
? ? super.initState();
? ? print('4.KSJApp的initState被調(diào)用');
? }
// 數(shù)據(jù)改變依賴的時(shí)候會(huì)發(fā)生改變并調(diào)用
// 情況1:調(diào)用 initState會(huì)調(diào)用
// 情況2:從其他對(duì)象中依賴一些數(shù)據(jù)發(fā)生改變時(shí),比如前面我們提到的inheritedWidget(這個(gè)后面會(huì)講到)
? @override
? void didChangeDependencies() {
// TODO: implement didChangeDependencies
? ? super.didChangeDependencies();
? ? print('didChangeDependencies');
? }
@override
? void didUpdateWidget(KSJApp oldWidget) {
// TODO: implement didUpdateWidget
? ? super.didUpdateWidget(oldWidget);
? ? print('KSJ的didUpdateWidget');
? }
@override
? Widgetbuild(BuildContext context) {
print('5.KSJApp的build被調(diào)用');
? ? return Center(
child:Column(
children:?[
Text('$_counter'),
? ? ? ? ? RaisedButton(child:Text("增加"), onPressed: (){
// set方法的調(diào)用會(huì)觸發(fā)build的方法的使用
? ? ? ? ? ? print('set方法的調(diào)用會(huì)觸發(fā)build的方法的調(diào)用');
? ? ? ? ? ? setState(() {
_counter++;
? ? ? ? ? ? });
? ? ? ? ? })
],
? ? ? ),
? ? );
? }
@override
? void dispose() {
// TODO: implement dispose
? ? print('6.KSJApp的dispose被調(diào)用');
? ? super.dispose();
? }
}
