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