Flutter生命週期的獲取

JavaNoober 發表於 2019-11-28

在Android開發中,系統對Activity、Fragment的生命週期有著非常明顯且較於區分的定義,但是在flutter中,由於flutter的生命週期依附在activity或fragment,它的生命週期就不同以往了,下面就展示以下flutter生命週期的理解。

flutter 生命週期相關函式的呼叫過程

首先,先上一張圖,這張圖很簡單明瞭的闡釋了一個頁面啟動所要執行的widget方法流程:

https://user-gold-cdn.xitu.io/2019/11/28/16eb1544520f9184?w=485&h=671&f=png&s=57147

下面解釋一下各個方法的作用:

initState

在生命週期中只呼叫一次,此時無法獲取widget物件,可以做一些初始化操作。

didChangeDependencies

當State物件的依賴發生變化時會被呼叫;例如:在之前build() 中包含了一個InheritedWidget,然後在之後的build() 中InheritedWidget發生了變化,那麼此時InheritedWidget的子widget的didChangeDependencies()回撥都會被呼叫。InheritedWidget這個widget可以由父控制元件向子控制元件共享資料,案例可以參考 scoped_model開源庫。

didUpdateWidget

widget狀態改變的時候呼叫

deactivate

類似於Activity的onResume和onStop,兩種狀態都會呼叫

dispose

類似於Android的onDestroy

上面的介紹都比較簡單,下面則介紹以下,如何去獲取app的生命週期

flutter app的生命週期

flutter提供了一個列舉類來代表了app各個生命週期的狀態:

enum AppLifecycleState {
  /// The application is visible and responding to user input.
  resumed,

  /// The application is in an inactive state and is not receiving user input.
  ///
  /// On iOS, this state corresponds to an app or the Flutter host view running
  /// in the foreground inactive state. Apps transition to this state when in
  /// a phone call, responding to a TouchID request, when entering the app
  /// switcher or the control center, or when the UIViewController hosting the
  /// Flutter app is transitioning.
  ///
  /// On Android, this corresponds to an app or the Flutter host view running
  /// in the foreground inactive state.  Apps transition to this state when
  /// another activity is focused, such as a split-screen app, a phone call,
  /// a picture-in-picture app, a system dialog, or another window.
  ///
  /// Apps in this state should assume that they may be [paused] at any time.
  inactive,

  /// The application is not currently visible to the user, not responding to
  /// user input, and running in the background.
  ///
  /// When the application is in this state, the engine will not call the
  /// [Window.onBeginFrame] and [Window.onDrawFrame] callbacks.
  ///
  /// Android apps in this state should assume that they may enter the
  /// [suspending] state at any time.
  paused,

  /// The application will be suspended momentarily.
  ///
  /// When the application is in this state, the engine will not call the
  /// [Window.onBeginFrame] and [Window.onDrawFrame] callbacks.
  ///
  /// On iOS, this state is currently unused.
  suspending,
}
複製程式碼

resumed

應用程式對使用者可見的時候輸出

inactive

介面處於不可點選狀態,但是可見時候的回撥,類似於Android的onpause

paused

app處於不可見的時候,類似於Android的onStop

suspending

ios中這個屬性無效,android中代表處於後臺

獲取方法

class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
  AppLifecycleState _lastLifecycleState;
 
  void dispose() {
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
  }
 
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }
 
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    print(state);
  }
 
  ...
}
複製程式碼

注意:第一次進入的時候並不會執行didChangeAppLifecycleState方法。
獲取app的生命週期方法很簡單,但是注意這並不是當前widget的生命週期,那我們如果獲取當前頁面的生命週期呢。

獲取flutter頁面的生命週期

當flutter頁面跳轉切入後臺,flutter並沒有清楚的給我們展示flutter頁面的各個生命週期狀態。如果我們想要獲取某個widget頁面的狀態,比如可見不可見那該如何操作呢?

flutter頁面的onDestroy

這個比較簡單,重寫State的dispose,這個方法即可理解為頁面的onDestroy操作。

flutter頁面的onStop、onResume

上面介紹了deactivate類似於activity的onResume、onStop那麼我們可以利用這個函式來自己標誌一下生命週期。
因為deactivate這個方法第一次是不執行的,因此我們可以定義一個預設值isVisible為true來代表是否可見。

class MyState extends State<StatefulWidget>{


  bool isVisible = true;

  @override
  void deactivate() {
    isVisible = !isVisible;
    if(isVisible){
      //onResume
    }else {
      //onStop
    }
    super.deactivate();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return null;
  }

}
複製程式碼

這時候我們就可以通過isVisible來判斷當前頁面是否可見了,以此來做一些操作。