Flutter 中的生命週期分析

龍湫發表於2020-03-04

本篇主要介紹Flutter中的相關生命週期 分為 widget生命週期、app生命週期

Widget生命週期

flutter中widget主要分為 StatelessWidget 和 StatefulWidget 兩種 二者生命週期不太一樣

StatelessWidget(無狀態)

如果一個控制元件自身狀態不會去改變,建立了就直接顯示,不會有色值、大小或者其他屬性的變化,這種widget一般都是繼承自StatelessWidget,常見的有Container、ScrollView等,生命週期只有 build

class Frog extends StatelessWidget {
  const Frog({ Key key }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Container(color: const Color(0xFF2DBD3A));
  }
}
複製程式碼

build是用來建立widget的,但是因為build在每次重新整理時候都會呼叫,通常需要把業務邏輯寫到建構函式中

StatefulWidget (有狀態)

需要持有狀態 State,這裡麵包含了一系列生命週期方法

class YellowBird extends StatefulWidget {
  const YellowBird({ Key key }) : super(key: key);

  @override
  _YellowBirdState createState() => new _YellowBirdState();
}

class _YellowBirdState extends State<YellowBird> {
  @override
  Widget build(BuildContext context) {
    return new Container(color: const Color(0xFFFFE306));
  }
}
複製程式碼

官網示意圖如下

image.png

在網上看到一個更加下詳細的

image.png

大致可以劃分3個階段:

  • 初始化

建構函式 > initState > didChangeDependencies > Widget build , 此時頁面載入完成。

  • 狀態變化
  • 元件移除

元件移除,例如頁面銷燬的時候會依次執行:deactivate > dispose

名稱 描述 呼叫次數
createState createState 是 StatefulWidget 裡建立 State 的方法,當要建立新的 StatefulWidget 的時候,會立即執行 createState,而且只執行一次 1次
initState initState 是 StatefulWidget 建立完後呼叫的第一個方法,而且只執行一次,類似於 Android 的 onCreate、iOS 的 viewDidLoad(),所以在這裡 View 並沒有渲染,但是這時 StatefulWidget 已經被載入到渲染樹裡了,這時 StatefulWidget 的 mount的值會變為 true,直到 dispose呼叫的時候才會變為 false。可以在 initState裡做一些初始化的操作。 1次
didChangeDependencies 1、當 StatefulWidget 第一次建立的時候,didChangeDependencies方法會在 initState方法之後立即呼叫,之後當 StatefulWidget 重新整理的時候,就不會呼叫了,
2、或者你的 StatefulWidget 依賴的 InheritedWidget 發生變化之後,didChangeDependencies才會呼叫,所以 didChangeDependencies有可能會被呼叫多次。
1次或多次
build 在 StatefulWidget 第一次建立的時候,build方法會在 didChangeDependencies方法之後立即呼叫,另外一種會呼叫 build方法的場景是,每當 UI 需要重新渲染的時候(setState觸發),build都會被呼叫,所以 build會被多次呼叫,然後 返回要渲染的 Widget。千萬不要在 build裡做除了建立 Widget 之外的操作,因為這個會影響 UI 的渲染效率 多次
didUpdateWidget 祖先節點rebuild widget時呼叫,當元件改變狀態時就會呼叫,
需要注意的是,涉及到controller的變更,需要在這個函式中移除老的controller的監聽,並建立新controller的監聽。
1次或多次
deactivate 當要將 State 物件從渲染樹中移除的時候,就會呼叫 deactivate生命週期,這標誌著 StatefulWidget 將要銷燬,但是有時候 State 不會被銷燬,而是重新插入到渲染樹種 1次或多次
dispose 當 View 不需要再顯示,從渲染樹中移除的時候,State 就會永久的從渲染樹中移除,就會呼叫 dispose生命週期,這時候就可以在 dispose裡做一些取消監聽、動畫的操作,和 initState是相反的 1次

這裡補充一個,**addPostFrameCallback,**是 StatefulWidge 渲染結束的回撥,只會被呼叫一次,之後 StatefulWidget 需要重新整理 UI 也不會被呼叫,addPostFrameCallback的使用方法是在 initState裡新增回撥:

import 'package:flutter/scheduler.dart';
@override
void initState() {
  super.initState();
  SchedulerBinding.instance.addPostFrameCallback((_) => {});
}
複製程式碼

App生命週期

在 window.dart中有列舉類 AppLifecycleState

enum AppLifecycleState {
  resumed,
  
  inactive,
  
  paused,

  suspending,
}
複製程式碼

如果想要知道Flutter App的生命週期,比如前臺、後臺就需要使用**WidgetsBindingObserver **使用方法如下

State的類mix WidgetsBindingObserver,覆寫didChangeAppLifecycleState

class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
    @override
  	void initState(){
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }
  
  	@override
  	void dispose() {
    // TODO: implement dispose
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
  }
  
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.paused) {
      // went to Background
    }
    if (state == AppLifecycleState.resumed) {
      // came back to Foreground
    }
  }
}
複製程式碼

# 參考

相關文章