網(wǎng)站首頁 編程語言 正文
引言
在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è)務(wù)數(shù)據(jù),可以理解為具有動態(tài)可交互的內(nèi)容界面,會根據(jù)數(shù)據(jù)的變化進行多次渲染。
StatefulWidget生命周期詳細分析
1. createState
當(dāng)StatefulWidget被創(chuàng)建時立即執(zhí)行createState。createState 函數(shù)執(zhí)行完畢后表示當(dāng)前組件已經(jīng)在 Widget 樹中,此時有一個非常重要的屬性mounted設(shè)置為true。
2. initState
該函數(shù)為 State 初始化調(diào)用,只會被調(diào)用一次。因此,通常會在該回調(diào)中做一些一次性的操作,如執(zhí)行 State 各變量的初始賦值,獲取服務(wù)端數(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í)行多次而導(dǎo)致狀態(tài)異常。因此此方法可以在每一幀中調(diào)用,此方法中應(yīng)該只包含構(gòu)建組件的代碼,不應(yīng)該包含其他額外的功能,尤其是耗時任務(wù)。
5. didUpdateWidget
該函數(shù)主要是在組件重新構(gòu)建,比如說熱重載,父組件發(fā)生 build 的情況下,子組件該方法才會被調(diào)用,其次該方法調(diào)用之后一定會再調(diào)用本組件中的 build 方法。此方法中通常會用當(dāng)前組件與前組件進行對比。Framework 調(diào)用完此方法后,會將組件設(shè)置為 dirty 狀態(tài),然后調(diào)用 build 方法,因此無需在此方法中調(diào)用 setState 方法。
6. deactivate
在組件被移除節(jié)點后會被調(diào)用,在某些情況下,框架將重新插入 State 對象到樹的其他位置(例如,如果包含該樹的子樹 State 對象從樹中的一個位置移植到另一位置),框架將會調(diào)用 build 方法來提供 State 對象適應(yīng)其在樹中的新位置。
7. dispose
永久移除組件,并釋放組件資源。調(diào)用完 dispose后,mounted 屬性被設(shè)置為 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('應(yīng)用程序可見且響應(yīng)用戶輸入。');
break;
case AppLifecycleState.paused:
print('應(yīng)用程序不可見且無法響應(yīng)用戶輸入,運行在后臺。');
break;
case AppLifecycleState.inactive:
print('應(yīng)用程序處于非激活狀態(tài),無法響應(yīng)用戶輸入。');
break;
case AppLifecycleState.detached:
print('應(yīng)用程序仍寄存在Flutter引擎上,但與平臺 View 分離。');
break;
}
}
// 當(dāng)前系統(tǒng)改變了一些訪問性活動的回調(diào)
@override
void didChangeAccessibilityFeatures() {
super.didChangeAccessibilityFeatures();
print("didChangeAccessibilityFeatures");
}
// 低內(nèi)存回調(diào)
@override
void didHaveMemoryPressure() {
super.didHaveMemoryPressure();
print("didHaveMemoryPressure");
}
// 用戶本地設(shè)置變化時調(diào)用,如系統(tǒng)語言改變
@override
void didChangeLocales(List<Locale> locale) {
super.didChangeLocales(locale);
print("didChangeLocales");
}
// 應(yīng)用尺寸改變時回調(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:應(yīng)用程序可見且響應(yīng)用戶輸入。
inactive:應(yīng)用程序處于非激活狀態(tài),無法響應(yīng)用戶輸入。在iOS上,打電話、響應(yīng)TouchID請求、進入應(yīng)用程序切換器或控制中心都處于此狀態(tài)。在Android上,分屏應(yīng)用,打電話,彈出系統(tǒng)對話框或其他窗口等。
pause:應(yīng)用程序不可見且無法響應(yīng)用戶輸入,運行在后臺。處于此狀態(tài)時,引擎將不會調(diào)用 Window.onBeginFrame 和 Window.onDrawFrame。
detached:應(yīng)用程序仍寄存在Flutter引擎上,但與平臺 View 分離。處于此狀態(tài)的時機:引擎首次加載到附加 到一個平臺 View的過程中,或者由于執(zhí)行 Navigator pop ,view 被銷毀。
結(jié)束語
原文鏈接:https://juejin.cn/post/7168709152808648735
相關(guān)推薦
- 2022-08-12 python關(guān)于字典及遍歷的常用方法_python
- 2022-12-07 進程狀態(tài)ps?-ef中的e、f含義講解_linux shell
- 2022-03-16 淺析ORB、SURF、SIFT特征點提取方法以及ICP匹配方法_C 語言
- 2022-02-24 Matlab中plot函數(shù)及l(fā)egend函數(shù)詳解
- 2023-02-17 golang基礎(chǔ)之waitgroup用法以及使用要點_Golang
- 2022-09-04 Python運行出現(xiàn)DeprecationWarning的問題及解決_python
- 2022-05-01 oracle刪除超過N天數(shù)據(jù)腳本的方法_oracle
- 2022-10-22 SQL?Server實現(xiàn)group_concat功能的詳細實例_MsSql
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支