Flutter組件生命周期和App生命周期示例解析
引言
在Flutter開發(fā)中,所有的組件和頁面都繼承自Widget,所以探索頁面的生命周期其實就是Widget的生命周期。 在 Flutter 中一切皆 組件,而組件又分為 StatefulWidget(有狀態(tài)) 和 StatelessWidget(無狀態(tài))組件
無狀態(tài)組件(StatelessWidget)
無狀態(tài)組件,可以理解為將外部傳入的數(shù)據(jù)轉(zhuǎn)化為界面展示的內(nèi)容,只會渲染一次。
有狀態(tài)組件(StatefulWidget)
有狀態(tài)組件,是定義交互邏輯和業(yè)務數(shù)據(jù),可以理解為具有動態(tài)可交互的內(nèi)容界面,會根據(jù)數(shù)據(jù)的變化進行多次渲染。
StatefulWidget生命周期詳細分析
1. createState
當StatefulWidget被創(chuàng)建時立即執(zhí)行createState。createState 函數(shù)執(zhí)行完畢后表示當前組件已經(jīng)在 Widget 樹中,此時有一個非常重要的屬性mounted設置為true。
2. initState
該函數(shù)為 State 初始化調(diào)用,只會被調(diào)用一次。因此,通常會在該回調(diào)中做一些一次性的操作,如執(zhí)行 State 各變量的初始賦值,獲取服務端數(shù)據(jù)等。
3. didChangeDependencies
該函數(shù)是在該組件依賴的 State 發(fā)生變化時會被調(diào)用。didChangeDependencies 方法調(diào)用后,組件的狀態(tài)變?yōu)?dirty,立即調(diào)用 build 方法。
4. build
主要是在方法中創(chuàng)建各種組件,繪制到屏幕上,由于 build 會被調(diào)用多次,因此在該函數(shù)中只能做返回 Widget 相關(guān)邏輯,避免因為執(zhí)行多次而導致狀態(tài)異常。因此此方法可以在每一幀中調(diào)用,此方法中應該只包含構(gòu)建組件的代碼,不應該包含其他額外的功能,尤其是耗時任務。
5. didUpdateWidget
該函數(shù)主要是在組件重新構(gòu)建,比如說熱重載,父組件發(fā)生 build 的情況下,子組件該方法才會被調(diào)用,其次該方法調(diào)用之后一定會再調(diào)用本組件中的 build 方法。此方法中通常會用當前組件與前組件進行對比。Framework 調(diào)用完此方法后,會將組件設置為 dirty 狀態(tài),然后調(diào)用 build 方法,因此無需在此方法中調(diào)用 setState 方法。
6. deactivate
在組件被移除節(jié)點后會被調(diào)用,在某些情況下,框架將重新插入 State 對象到樹的其他位置(例如,如果包含該樹的子樹 State 對象從樹中的一個位置移植到另一位置),框架將會調(diào)用 build 方法來提供 State 對象適應其在樹中的新位置。
7. dispose
永久移除組件,并釋放組件資源。調(diào)用完 dispose后,mounted 屬性被設置為 false,也代表組件生命周期的結(jié)束,此時再調(diào)用 setState 方法將會拋出異常。
8. reassemble
主要在開發(fā)階段使用,在 debug 模式下,每次熱重載都會調(diào)用該函數(shù),因此在 debug 階段可以在此期間增加一些 debug 代碼,來檢查代碼問題。
App生命周期
App的生命周期的監(jiān)聽,在Flutter中需要通過監(jiān)聽器WidgetsBindingObserver監(jiān)聽器中的AppLifecycleState方法來是實現(xiàn)。
class AppLifePage extends StatefulWidget { CEAppLifePage({Key key}) : super(key: key); @override _AppLifePageState createState() => _AppLifePageState(); } // 實現(xiàn)WidgetsBindingObserver觀察者 class _AppLifePageState extends State<AppLifePage> with WidgetsBindingObserver{ @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); //添加觀察者 } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("App生命周期"),), body: Text('Flutter App 生命周期'), ); } @override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); print("didChangeAppLifecycleState: $state"); switch (state) { case AppLifecycleState.resumed: print('應用程序可見且響應用戶輸入。'); break; case AppLifecycleState.paused: print('應用程序不可見且無法響應用戶輸入,運行在后臺。'); break; case AppLifecycleState.inactive: print('應用程序處于非激活狀態(tài),無法響應用戶輸入。'); break; case AppLifecycleState.detached: print('應用程序仍寄存在Flutter引擎上,但與平臺 View 分離。'); break; } } // 當前系統(tǒng)改變了一些訪問性活動的回調(diào) @override void didChangeAccessibilityFeatures() { super.didChangeAccessibilityFeatures(); print("didChangeAccessibilityFeatures"); } // 低內(nèi)存回調(diào) @override void didHaveMemoryPressure() { super.didHaveMemoryPressure(); print("didHaveMemoryPressure"); } // 用戶本地設置變化時調(diào)用,如系統(tǒng)語言改變 @override void didChangeLocales(List<Locale> locale) { super.didChangeLocales(locale); print("didChangeLocales"); } // 應用尺寸改變時回調(diào),例如旋轉(zhuǎn) @override void didChangeMetrics() { super.didChangeMetrics(); Size size = WidgetsBinding.instance.window.physicalSize; print("didChangeMetrics :寬:${size.width} 高:${size.height}"); } // 系統(tǒng)切換主題時回調(diào) @override void didChangePlatformBrightness() { super.didChangePlatformBrightness(); print("didChangePlatformBrightness"); } // 文字系數(shù)變化 @override void didChangeTextScaleFactor() { super.didChangeTextScaleFactor(); print( "didChangeTextScaleFactor :${WidgetsBinding.instance.window.textScaleFactor}"); } @override void dispose() { super.dispose(); WidgetsBinding.instance.removeObserver(this); // 銷毀觀察者 } }
重點是重寫 didChangeAppLifecycleState 方法,AppLifecycleState 中的狀態(tài)包括:resumed、inactive、paused、detached。
resumed:應用程序可見且響應用戶輸入。
inactive:應用程序處于非激活狀態(tài),無法響應用戶輸入。在iOS上,打電話、響應TouchID請求、進入應用程序切換器或控制中心都處于此狀態(tài)。在Android上,分屏應用,打電話,彈出系統(tǒng)對話框或其他窗口等。
pause:應用程序不可見且無法響應用戶輸入,運行在后臺。處于此狀態(tài)時,引擎將不會調(diào)用 Window.onBeginFrame 和 Window.onDrawFrame。
detached:應用程序仍寄存在Flutter引擎上,但與平臺 View 分離。處于此狀態(tài)的時機:引擎首次加載到附加 到一個平臺 View的過程中,或者由于執(zhí)行 Navigator pop ,view 被銷毀。
結(jié)束語
以上就是Flutter組件生命周期和App生命周期示例解析的詳細內(nèi)容,更多關(guān)于Flutter 組件APP生命周期的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android開發(fā)Intent跳轉(zhuǎn)傳遞list集合實現(xiàn)示例
這篇文章主要為大家介紹了Android開發(fā)Intent跳轉(zhuǎn)傳遞list集合實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-07-07TabLayout+ViewPager實現(xiàn)切頁的示例代碼
這篇文章主要介紹了TabLayout+ViewPager實現(xiàn)切頁的示例代碼,可實現(xiàn)左右滑動切換視圖界面和點擊切換,非常具有實用價值,需要的朋友可以參考下2019-01-01Android開發(fā)中Intent.Action各種常見的作用匯總
今天小編就為大家分享一篇關(guān)于Android開發(fā)中Intent.Action各種常見的作用匯總,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12Android 圓角 ImageView類可設置弧度(代碼簡單)
這篇文章主要介紹了Android 圓角 ImageView類可設置弧度 的相關(guān)資料,需要的朋友可以參考下2016-03-03Android 跨進程SharedPreferences異常詳解
這篇文章主要介紹了Android 跨進程SharedPreferences異常詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05淺析Android圓形進度條ProgressBar如何實現(xiàn)固定進度
之前遇到一個問題,發(fā)現(xiàn)Android里的圓形進度條無法固定一個進度,所以這篇文章就來和大家探索一下圓形進度條ProgressBar如何實現(xiàn)固定進度,希望對大家有所幫助2024-03-03Android車載多媒體開發(fā)MediaSession框架示例詳解
這篇文章主要為大家介紹了Android車載多媒體開發(fā)MediaSession框架示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10