2.2 State生命週期
前面說過了StatefullWidget,這節咱們來講說State的生命週期,這在flutter開發中是很是重要的。web
2.2.1實測
寫個有狀態類並混入WidgetsBindingObserver配合監聽特殊狀態及其一個按鈕,調用setState, 給生命週期的方法新增打印:安全
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: '生命週期', home: new LiftCycle(), ); }}
class LiftCycle extends StatefulWidget { @override _LiftCycleState createState() => _LiftCycleState();}
class _LiftCycleState extends State<LiftCycle> with WidgetsBindingObserver { int count = 0;
@override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); print('初始化 initState'); }
@override void didUpdateWidget(LiftCycle oldWidget) { super.didUpdateWidget(oldWidget); print('組件更新 didUpdateWidget'); }
@override void reassemble() { super.reassemble(); print('從新安裝 reassemble'); }
@override void deactivate() { super.deactivate(); print('停用 deactivate'); }
@override void dispose() { super.dispose(); WidgetsBinding.instance.removeObserver(this); print('銷燬 dispose'); }
@override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); print('特殊狀態 state:$state'); }
@override void setState(fn) { super.setState(fn); print('狀態刷新 setState'); }
@override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar(title: new Text('生命週期')), body: new Center( child: new FlatButton( onPressed: () => setState(() => count++), child: new Text('$count'), ), ), ); }
@override void didChangeDependencies() { super.didChangeDependencies(); print('依賴改變 didChangeDependencies'); }}
而後咱們如今來看看打印流程,正常打開App什麼都不操做,就打印了:微信
I/flutter (15867): 初始化 initStateI/flutter (15867): 依賴改變 didChangeDependenciesI/flutter (15867): 從新安裝 reassembleI/flutter (15867): 組件更新 didUpdateWidget
熱重載打印:app
I/flutter (16141): 從新安裝 reassembleI/flutter (16141): 組件更新 didUpdateWidgetReloaded 0 of 468 libraries in 186ms.
點擊按鈕打印:框架
I/flutter (16141): 狀態刷新 setState// count也+1了,說明從新調用過build。
2.2.2流程圖
圖解主要部分:less
-
1.構建 (build)
; -
2.若是用戶調用了 setState
時則狀態刷新,從新build; -
3.若是銷燬先停用而後 dispose
銷燬再結束;
構造函數
構造函數不屬於生命週期,必然是要第一個調用的,也就是調用前State的widget屬性爲空。編輯器
initState 初始化
當此對象插入樹中時調用,框架會調用一次此方法並不會再次重複執行, 若是[State]
的[build]
方法依賴於自己能夠更改狀態的對象,例如[ChangeNotifier]
或[Stream]
, 或者某些其餘能夠訂閱的對象接收通知,能夠在此方法訂閱,但記得去dispose取消訂閱;ide
didChangeDependencies 依賴改變
顧名思義,依賴項更改時調用,但也會在initState以後調用, 在這個方法調用[BuildContext.inheritFromWidgetOfExactType]
是安全的。函數
build 構建
會在如下場景調用:flex
-
initState()
以後; -
didUpdateWidget()
以後; -
setState()
以後。 -
didChangeDependencies()
以後。 -
State對象從樹中一個位置移除後會調用 deactivate
,而後又從新插入到樹的其它位置以後。
reassemble 從新安裝
專門爲了開發調試而提供的,在熱重載(hot reload)時會被調用,此回調在Release模式下永遠不會被調用。
didUpdateWidget 組件更新
當組件的狀態改變的時候就會調用didUpdateWidget()
,好比調用了setState()
, 在widget從新構建時,Flutter framework會調用Widget.canUpdate
來檢測Widget樹中同一位置的新舊節點, 而後決定是否須要更新,若是Widget.canUpdate
返回true則會調用此回調。正如以前所述,Widget.canUpdate
會在 新舊widget的key和runtimeType同時相等時會返回true,也就是說在新舊widget的key和runtimeType同時相等時didUpdateWidget()
就會被調用。
deactivate 暫停
State對象從樹中被移除時(在dispose以前),會調用這個函數來將對象暫停。
dispose 銷燬
當State對象被銷燬時調用,一般在此回調中釋放資源和移除監聽。
【 特殊狀態 】
咱們自定義的State類混入了WidgetsBindingObserver
,因此可使用他的暫停和恢復,
初始化:
@overridevoid initState() { super.initState(); WidgetsBinding.instance.addObserver(this); // 在這初始化了 print('初始化 initState');}
銷燬:
@overridevoid dispose() { super.dispose(); WidgetsBinding.instance.removeObserver(this); // 在這銷燬 print('銷燬 dispose');}
使用:
@overridevoid didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); print('特殊狀態 state:$state');}
這個didChangeAppLifecycleState
是WidgetsBindingObserver
類的一個方法, 能夠用來判斷當前的狀態是在前臺仍是後臺。
這個方法接收一個AppLifecycleState
類型的枚舉:
枚舉值 | 含義 |
---|---|
resumed | 程序可見,並響應用戶輸入。 |
inactive | 處於非活動狀態,未收到用戶輸入。 |
paused | 程序當前不可見,不響應用戶輸入,而且在後臺運行。 |
suspending | 程序將暫時暫停。 |
AppLifecycleState實測
當App返回到桌面或者其餘不可見狀態,但並未結束:
I/flutter ( 2428): 特殊狀態 state:AppLifecycleState.inactiveI/flutter ( 2428): 特殊狀態 state:AppLifecycleState.paused
當App回到可見狀態:
I/flutter ( 2428): 特殊狀態 state:AppLifecycleState.inactiveI/flutter ( 2428): 特殊狀態 state:AppLifecycleState.resumed
流程圖:
本文分享自微信公衆號 - flutter開發精選(Study_Knowledge)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。