說明: 本篇文章已受權微信公衆號 Flutter那些事 獨家發佈,未經受權,嚴禁轉載!java
1. 前言 在初學新技術以前,咱們總會要從最基本的東西瞭解起來,就比如當接觸Android的時候,咱們學四大組件都要學很久,是否還記得在Android的生命週期?首先讓咱們回顧下Android中的生命週期 bash
1.啓動Activity:系統會先調用onCreate方法,而後調用onStart方法,最後調用onResume,Activity進入運行狀態。
2.當前Activity被其餘Activity覆蓋其上或被鎖屏:系統會調用onPause方法,暫停當前Activity的執行。
3.當前Activity由被覆蓋狀態回到前臺或解鎖屏:系統會調用onResume方法,再次進入運行狀態。
4.當前Activity轉到新的Activity界面或按Home鍵回到主屏,自身退居後臺:系統會先調用onPause方法,而後調用onStop方法,進入停滯狀態。
5.用戶後退回到此Activity:系統會先調用onRestart方法,而後調用onStart方法,最後調用onResume方法,再次進入運行狀態。
6.當前Activity處於被覆蓋狀態或者後臺不可見狀態,即第2步和第4步,系統內存不足,殺死當前Activity,然後用戶退回當前Activity:再次調用onCreate方法、onStart方法、onResume方法,進入運行狀態。
7.用戶退出當前Activity:系統先調用onPause方法,而後調用onStop方法,最後調用onDestory方法,結束當前Activity。
複製代碼
emmm,相信小夥伴們如今應該記憶起來了吧,前戲好了,進入主題,聊聊咱們今天的主人公"State"。微信
2. Widget概念 在咱們的主人公出場前,先認識下他的小夥伴網絡
Flutter中幾乎全部的對象都是一個Widget,與原生開發中「控件」不一樣的是,
Flutter中的widget的概念更普遍,它不只能夠表示UI元素,也能夠表示一些功能性的組件如:用於手勢檢測的 GestureDetector widget、用於應用主題數據傳遞的Theme等等。
而原生開發中的控件一般只是指UI元素
複製代碼
3. State的引入app
abstract class StatelessWidget extends Widget 複製代碼
abstract class StatefulWidget extends Widget 複製代碼
從上述的代碼中咱們看到他們都繼承了一個東西Widget,那就先簡單的看下這個類less
@immutable
abstract class Widget extends DiagnosticableTree {
const Widget({ this.key });
final Key key;
@protected
Element createElement();
@override
String toStringShort() {
return key == null ? '$runtimeType' : '$runtimeType-$key';
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.dense;
}
static bool canUpdate(Widget oldWidget, Widget newWidget) {
return oldWidget.runtimeType == newWidget.runtimeType
&& oldWidget.key == newWidget.key;
}
}
複製代碼
上述代碼中有一個咱們很常見的方法,每次在繼承的時候都須要重寫的一個方法ide
@override
StatefulElement createElement() => StatefulElement(this);
複製代碼
繼續跟蹤StatefulElement發現存在一個*widget.createState()*方法,發現了就要繼續,寧殺錯,莫放過函數
class StatefulElement extends ComponentElement {
/// Creates an element that uses the given widget as its configuration.
StatefulElement(StatefulWidget widget)
: _state = widget.createState(),
super(widget) {
.....
assert(_state._element == null);
_state._element = this;
assert(_state._widget == null);
_state._widget = widget;
assert(_state._debugLifecycleState == _StateLifecycle.created);
}
複製代碼
點擊createState方法咱們終於找到了今天的主人公,沒錯,就是它,State,跑不掉了。測試
@protected
State createState();
複製代碼
@override
void initState() {
// TODO: implement initState
super.initState();
_loadItemPage();
}
複製代碼
咱們能夠將上述方法分爲三個部分進行描述,見下圖: ui
不屬於生命週期,由於這個時候State的widget屬性爲空,此時沒法在構造函數中訪問widget屬性
複製代碼
/// Called when this object is inserted into the tree.
這個函數在生命週期中只調用一次。這裏能夠作一些初始化工做,好比初始化State的變量
複製代碼
/// Called when a dependency of this [State] object changes.
這個函數會緊跟在initState以後調用
複製代碼
/// Called whenever the widget configuration changes.
當組件的狀態改變的時候就會調用didUpdateWidget,好比調用了setStat
複製代碼
/// Called when this object is removed from the tree.
在dispose以前,會調用這個函數。
複製代碼
/// Called when this object is removed from the tree permanently.
一旦到這個階段,組件就要被銷燬了,這個函數通常會移除監聽,清理環境。
複製代碼
這個函數在生命週期中只調用一次。這裏能夠作一些初始化工做,好比初始化State的變量。
大致這樣吧,最後來個圖表總結下
階段 | 調用次數 | 是否支持setState |
---|---|---|
構造函數 | 1 | 否 |
initState | 1 | 支持但無效(使用setState和不使用同樣) |
didChangeDependencies | >=1 | 支持但無效 |
didUpdateWidget | >=1 | 支持但無效 |
deactivate | >=1 | 否 |
dispose | 1 | 否 |
import 'package:flutter/material.dart';
class LifeState extends StatefulWidget {
@override
_lifeStates createState() => _lifeStates();
}
class _lifeStates extends State<LifeState> {
@override
void initState() {
// TODO: implement initState
super.initState();
print('initState');
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
print(state.toString());
}
@override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
print('didChangeDependencies');
}
@override
void didUpdateWidget(LifeState 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() {
// TODO: implement reassemble
super.reassemble();
print('reassemble');
}
@override
void deactivate() {
// TODO: implement deactivate
super.deactivate();
print('deactivate');
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
print('dispose');
}
}
複製代碼
測試結果
initState
didChangeDependencies
build
複製代碼
deactivate
dispose
複製代碼
reassemble
didUpdateWidget
build
複製代碼
AppLifecycleState.inactive
AppLifecycleState.paused
複製代碼
AppLifecycleState.inactive
AppLifecycleState.resumed
複製代碼