在Android開發中,系統對Activity、Fragment的生命週期有著非常明顯且較於區分的定義,但是在flutter中,由於flutter的生命週期依附在activity或fragment,它的生命週期就不同以往了,下面就展示以下flutter生命週期的理解。
flutter 生命週期相關函式的呼叫過程
首先,先上一張圖,這張圖很簡單明瞭的闡釋了一個頁面啟動所要執行的widget方法流程:
下面解釋一下各個方法的作用:
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來判斷當前頁面是否可見了,以此來做一些操作。