Flutter 的生命週期

小德_REN發表於2019-06-25

前言

如果你是 Android、iOS、React、Vue 的開發人員,那麼你一定不會對生命週期感到陌生,當你在學習 Flutter 的時候,Flutter 也有自己的生命週期。本篇文章就講講 Flutter 的生命週期,從而知道應該在哪裡來寫業務邏輯。

Flutter 的生命週期

Flutter 的生命週期分為兩個部分:

  1. Widget 的生命週期
  2. App 的生命週期

Flutter 裡的 Widget 指的就是 View,所以 Widget 的生命週期就是 View 的建立和銷燬等,但是如果你想知道 App 是在前臺還是後臺,這時就需要用到 App 的生命週期。

Widget 的生命週期

Flutter 裡的 Widget 分為 StatelessWidget 和 StatefulWidget 兩種,這兩種 Widget 的生命週期是不一樣的,我們接下來具體來看。

StatelessWidget 的生命週期

StatelessWidget 的生命週期只有一個,就是:

  • build

    build 是用來建立 Widget 的,但因為 build 在每次介面重新整理的時候都會呼叫,所以不要在 build 裡寫業務邏輯,可以把業務邏輯寫到你的 StatelessWidget 的建構函式裡。

    StatelessWidget 的 build 函式程式碼如下:

    class TestWidget extends StatelessWidget{
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        print('StatelessWidget build');
        return Text('Test');
      }
    }
    複製程式碼

StatefulWidget 的生命週期

StatefulWidget 的生命週期比較複雜,依次為:

  • createState
  • initState
  • didChangeDependencies
  • build
  • addPostFrameCallback
  • didUpdateWidget
  • deactivate
  • dispose

接下來具體介紹一下各個生命週期。

  • createState

    createState 是 StatefulWidget 裡建立 State 的方法,當要建立新的 StatefulWidget 的時候,會立即執行 createState,而且只執行一次,createState 必須要實現:

    class MyScreen extends StatefulWidget {
      @override
      _MyScreenState createState() => _MyScreenState();
    }
    複製程式碼
  • initState

    前面的 createState 是在建立 StatefulWidget 的時候會呼叫,initState 是 StatefulWidget 建立完後呼叫的第一個方法,而且只執行一次,類似於 Android 的 onCreate、iOS 的 viewDidLoad(),所以在這裡 View 並沒有渲染,但是這時 StatefulWidget 已經被載入到渲染樹裡了,這時 StatefulWidget 的 mount 的值會變為 true,直到 dispose 呼叫的時候才會變為 false。可以在 initState 裡做一些初始化的操作。

    在 override initState 的時候必須要呼叫 super.initState():

    @override
    void initState() {
      super.initState();
      ...
    }
    複製程式碼
  • didChangeDependencies

    當 StatefulWidget 第一次建立的時候,didChangeDependencies 方法會在 initState 方法之後立即呼叫,之後當 StatefulWidget 重新整理的時候,就不會呼叫了,除非你的 StatefulWidget 依賴的 InheritedWidget 發生變化之後,didChangeDependencies 才會呼叫,所以 didChangeDependencies 有可能會被呼叫多次。

  • build

    在 StatefulWidget 第一次建立的時候,build 方法會在 didChangeDependencies 方法之後立即呼叫,另外一種會呼叫 build 方法的場景是,每當 UI 需要重新渲染的時候,build 都會被呼叫,所以 build 會被多次呼叫,然後 返回要渲染的 Widget。千萬不要在 build 裡做除了建立 Widget 之外的操作,因為這個會影響 UI 的渲染效率。

  • addPostFrameCallback

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

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

    didUpdateWidget 這個生命週期我們一般不會用到,只有在使用 key 對 Widget 進行復用的時候才會呼叫。

  • deactivate

    當要將 State 物件從渲染樹中移除的時候,就會呼叫 deactivate 生命週期,這標誌著 StatefulWidget 將要銷燬,但是有時候 State 不會被銷燬,而是重新插入到渲染樹種。

  • dispose

    當 View 不需要再顯示,從渲染樹中移除的時候,State 就會永久的從渲染樹中移除,就會呼叫 dispose 生命週期,這時候就可以在 dispose 裡做一些取消監聽、動畫的操作,和 initState 是相反的。

App 的生命週期

如果想要知道 Flutter App 的生命週期,例如 Flutter 是在前臺還是在後臺,就需要使用到 WidgetsBindingObserver 了,使用方法如下:

  1. State 的類 mix WidgetsBindingObserver:

    class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
        ...
    }
    複製程式碼
  2. 在 State 的 initState 裡新增監聽:

    @override
      void initState(){
        super.initState();
        WidgetsBinding.instance.addObserver(this);
      }
    複製程式碼
  3. 在 State 的 dispose 裡移除監聽:

      @override
      void dispose() {
        // TODO: implement dispose
        super.dispose();
        WidgetsBinding.instance.removeObserver(this);
      }
    複製程式碼
  4. 在 State 裡 override didChangeAppLifecycleState

    @override
    void didChangeAppLifecycleState(AppLifecycleState state) {
      super.didChangeAppLifecycleState(state);
      if (state == AppLifecycleState.paused) {
        // went to Background
      }
      if (state == AppLifecycleState.resumed) {
        // came back to Foreground
      }
    }
    複製程式碼

AppLifecycleState 就是 App 的生命週期,有:

  • resumed
  • inactive
  • paused
  • suspending

相關文章