項(xiàng)目地址:https://github.com/Code-Yeong/FlutterDemo
1、引言
在開發(fā)flutter項(xiàng)目過程中我們肯定離不開組件,無論是布局、動畫還是按鈕、標(biāo)簽,這些在flutter中都由大大小小的組件構(gòu)成。組件從創(chuàng)建、繪制到銷毀的各個(gè)階段都有不同的回調(diào)函數(shù)執(zhí)行相應(yīng)的任務(wù),這些回調(diào)函數(shù)也構(gòu)成了組件的生命周期。下面本文主要圍繞著
StatefullWidget的生命周期展開討論,希望對大家有所幫助。
2、StatefulWidget介紹
StatefulWidget是一個(gè)抽象類,使用時(shí)此組件只需要繼承這個(gè)類即可,下面是StatefulWidget的源碼:
abstract class StatefulWidget extends Widget {
/// Initializes [key] for subclasses.
const StatefulWidget({ Key key }) : super(key: key);
@override
StatefulElement createElement() => StatefulElement(this);
@protected
State createState();
}
在使用時(shí),子類需要重寫crateElement()函數(shù)和createState(),這兩個(gè)函數(shù)的主要作用是:前者在element樹中創(chuàng)建一個(gè)新的element,在此函數(shù)中用戶無需做任何修改;后者的作用是創(chuàng)建出一個(gè)state用于存儲組件的狀態(tài),值得注意的是同一個(gè)組件被創(chuàng)建多次,那么創(chuàng)建出的state數(shù)量和組件數(shù)一致,也就是說組件與state一一對應(yīng)。
createState()函數(shù)的返回值是一個(gè)State類型的對象,因此我們需要在這個(gè)函數(shù)中創(chuàng)建并返回一個(gè)State類型的值,首先我們看看State對應(yīng)的源碼(這里刪除了源碼中的注釋和一些無關(guān)的屬性、函數(shù),若有需要請對照官方文檔閱讀):
abstract class State<T extends StatefulWidget> extends Diagnosticable {
@protected
@mustCallSuper
void initState() {
assert(_debugLifecycleState == _StateLifecycle.created);
}
@mustCallSuper
@protected
void didUpdateWidget(covariant T oldWidget) { }
@protected
@mustCallSuper
void reassemble() { }
@protected
void setState(VoidCallback fn) {
//.......
_element.markNeedsBuild();
}
@protected
@mustCallSuper
void deactivate() { }
@protected
@mustCallSuper
void dispose() {
assert(_debugLifecycleState == _StateLifecycle.ready);
assert(() { _debugLifecycleState = _StateLifecycle.defunct; return true; }());
}
@protected
Widget build(BuildContext context);
@protected
@mustCallSuper
void didChangeDependencies() { }
}
這里保留了幾個(gè)與組件生命收起相關(guān)的函數(shù),分別是initState()、didUpdateWidget()、deactivate()、dispose()、build()以及didChangeDependencies(),其作用就不細(xì)說,下面開始探究其生命周期。
3、StatefulWidget組件生命周期
首先我們創(chuàng)建了一個(gè)TELifeCycleOfState類繼承自StatefulWidget,在它的兩個(gè)回調(diào)函數(shù)種分別向控制臺輸出log,代碼如下
class TELifeCycleOfState extends StatefulWidget {
@override
State createState() {
print("parent-->createState");
return _TELifeCycleOfState();
}
@override
StatefulElement createElement() {
print("parent-->createElement");
return StatefulElement(this);
}
}
然后在創(chuàng)建_TELifeCycleOfState類,繼承自State類并重寫其回調(diào)函數(shù),同樣我們在State的回調(diào)函數(shù)中分別向控制臺打印log。
class _TELifeCycleOfState extends State<TELifeCycleOfState{
num _count = 0;
@override
void initState() {
super.initState();
print("parent-->initState");
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
print("parent-->didChangeDependencies");
}
@override
Widget build(BuildContext context) {
print("parent-->build");
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.of(context).pop();
}),
title: Text("Test lifeCycle"),
),
body: Container(
child: Center(
child: Text('${_count}'),
),
),
floatingActionButton: IconButton(
icon: Icon(Icons.add),
onPressed: () {
setState(() {
_count++;
});
}),
);
}
@override
void dispose() {
print("parent-->dispose");
super.dispose();
}
@override
void deactivate() {
super.deactivate();
print("parent-->deactivate");
}
@override
void reassemble() {
super.reassemble();
print("parent-->reassemble");
}
@override
void didUpdateWidget(TELifeCycleOfState oldWidget) {
super.didUpdateWidget(oldWidget);
print("parent-->didUpdateWidget");
}
}
我們在頁面中添加了一個(gè)floatingActionButton,每次點(diǎn)擊這個(gè)按鈕,計(jì)數(shù)_count的值加1并顯示在頁面上。下面我們運(yùn)行代碼,觀察通過日志輸出詳情分析組件的生命周期函數(shù)執(zhí)行情況。

程序運(yùn)行起來之后什么都不干,我們首先再來查看log日志輸出情況:
flutter: parent-->createElement
flutter: parent-->createState
flutter: parent-->initState
flutter: parent-->didChangeDependencies
flutter: parent-->build
然后接著點(diǎn)擊右下角“+”按鈕讓計(jì)數(shù)加1,再觀察日志輸出情況:
flutter: parent-->createElement
flutter: parent-->createState
flutter: parent-->initState
flutter: parent-->didChangeDependencies
flutter: parent-->build
flutter: parent-->build
再接著按“home”件然程序進(jìn)入后臺,我們觀察到日志沒有任何變化,也就是說上述生命周期函數(shù)都沒有被執(zhí)行。
接著我們讓程序再次進(jìn)入前臺執(zhí)行,并推出頁面,日志變化如下:
flutter: parent-->createElement
flutter: parent-->createState
flutter: parent-->initState
flutter: parent-->didChangeDependencies
flutter: parent-->build
flutter: parent-->build
flutter: parent-->deactivate
flutter: parent-->dispose
至此,組件生命周期暫時(shí)已經(jīng)“結(jié)束”,我們總結(jié)一下,上述執(zhí)行過程中,組件生命周期大致是這么個(gè)情況:
createElement -> createState -> initState -> didChangeDependencies -> build -> deactivate -> dispose
對比一下Android中Activity的生命周期(下圖是從android官網(wǎng)摘取的圖片),我們發(fā)現(xiàn)flutter組件的生命周期缺少了onPause()、onResume()等回調(diào)函數(shù)。

與
Activity相比StatefulWidget“缺少”了幾個(gè)重要的生命周期函數(shù),是不是就意味著組件壓根兒就沒有呢。別擔(dān)心,其實(shí)StatefulWidget也可以有這幾個(gè)生命周期函數(shù),不過這幾個(gè)函數(shù)不再State中,而是在WidgetsBindingObserver中,通過mixin的方式將該組件的接口引入進(jìn)來之后,我們同樣也能實(shí)現(xiàn)向Activity類似的生命周期。下面我們對代碼進(jìn)行相應(yīng)的修改:
class _TELifeCycleOfState extends State<TELifeCycleOfState> with WidgetsBindingObserver {
num _count = 0;
@override
void initState() {
super.initState();
//新加內(nèi)容
WidgetsBinding.instance.addObserver(this);
print("parent-->initState");
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
print("parent-->didChangeDependencies");
}
@override
Widget build(BuildContext context) {
print("parent-->build");
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.of(context).pop();
}),
title: Text("Test lifeCycle"),
),
body: Container(
child: Center(
child: TETextWidget(
count: _count,
),
),
),
floatingActionButton: IconButton(
icon: Icon(Icons.add),
onPressed: () {
setState(() {
_count++;
});
}),
);
}
@override
void dispose() {
print("parent-->dispose");
//新加內(nèi)容
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void deactivate() {
super.deactivate();
print("parent-->deactivate");
}
@override
void reassemble() {
super.reassemble();
print("parent-->reassemble");
}
@override
void didUpdateWidget(TELifeCycleOfState oldWidget) {
super.didUpdateWidget(oldWidget);
print("parent-->didUpdateWidget");
}
//新加內(nèi)容
AppLifecycleState _state;
//新加內(nèi)容
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
_state = state;
print("state is --> : $_state");
}
}
然后我們在重復(fù)以上幾個(gè)步驟,得到一下日志輸出:
flutter: parent-->createElement
flutter: parent-->createState
flutter: parent-->initState
flutter: parent-->didChangeDependencies
flutter: parent-->build
flutter: parent-->build
flutter: state is -> AppLifecycleState.inactive
flutter: state is -> AppLifecycleState.paused
flutter: state is -> AppLifecycleState.inactive
flutter: state is -> AppLifecycleState.resumed
flutter: parent-->deactivate
flutter: parent-->dispose
這里的inactive狀態(tài)表示app進(jìn)入了后臺但可見,當(dāng)完全不可見之后才執(zhí)行paused。重新回到可見但不可操作時(shí)又會執(zhí)行一次inactive ,之后再resumed進(jìn)入running狀態(tài)。
我們將上述執(zhí)行直接總結(jié)起來,分析得出以下生命周期圖:

4、結(jié)束語
好啦,就將這么多了。沒有講清楚的地方請諸位多包涵,也歡迎提出修改意見。