Flutter核心技術與實戰 11 | 生命週期

State 生命週期

State 的生命週期能夠分爲 3 個階段:建立(插入視圖樹)、更新(在視圖樹中存在)、銷燬(從視圖樹中移除)。

建立

State 初始化時會依次執行 :構造方法 -> initState -> didChangeDependencies -> build,隨後完成頁面渲染。安全

  • 構造方法是 State 生命週期的起點,Flutter 會經過調用 StatefulWidget.createState() 來建立一個 State。咱們能夠經過構造方法,來接收父 Widget 傳遞的初始化 UI 配置數據。這些配置數據,決定了 Widget 最初的呈現效果。
  • initState,會在 State 對象被插入視圖樹的時候調用。這個函數在 State 的生命週期中只會被調用一次,因此咱們能夠在這裏作一些初始化工做,好比爲狀態變量設定默認值。
  • didChangeDependencies 則用來專門處理 State 對象依賴關係變化,會在 initState() 調用結束後,被 Flutter 調用。
  • build,做用是構建視圖。通過以上步驟,Framework 認爲 State 已經準備好了,因而調用 build。咱們須要在這個函數中,根據父 Widget 傳遞過來的初始化配置數據,以及 State 的當前狀態,建立一個 Widget 而後返回。

更新

Widget 的狀態更新,主要由 3 個方法觸發:setState、didchangeDependencies 與 didUpdateWidget。async

  • setState:咱們最熟悉的方法之一。當狀態數據發生變化時,咱們老是經過調用這個方法告訴 Flutter:「我這兒的數據變啦,請使用更新後的數據重建 UI!」
  • didChangeDependencies:State 對象的依賴關係發生變化後,Flutter 會回調這個方法,隨後觸發組件構建。哪些狀況下 State 對象的依賴關係會發生變化呢?典型的場景是,系統語言 Locale 或應用主題改變時,系統會通知 State 執行 didChangeDependencies 回調方法。
  • didUpdateWidget:當 Widget 的配置發生變化時,好比,父 Widget 觸發重建(即父 Widget 的狀態發生變化時),熱重載時,系統會調用這個函數。

一旦這三個方法被調用,Flutter 隨後就會銷燬老 Widget,並調用 build 方法重建 Widget。函數

銷燬

好比組件被移除,或是頁面銷燬的時候,系統會調用 deactivate 和 dispose 這兩個方法,來移除或銷燬組件。oop

  • 當組件的可見狀態發生變化時,deactivate 函數會被調用,這時 State 會被暫時從視圖樹中移除。值得注意的是,頁面切換時,因爲 State 對象在視圖樹中的位置發生了變化,須要先暫時移除後再從新添加,從新觸發組件構建,所以這個函數也會被調用。
  • 當 State 被永久地從視圖樹中移除時,Flutter 會調用 dispose 函數。而一旦到這個階段,組件就要被銷燬了,因此咱們能夠在這裏進行最終的資源釋放、移除監聽、清理環境,等等。

App 生命週期

在原生開發中,咱們能夠經過重寫 Activity、ViewController 生命週期回調方法,或是註冊應用程序的相關通知,來監聽 App 的生命週期並作相應的處理。而在 Flutter 中,咱們能夠利用 WidgetsBindingObserver 類,來實現一樣的需求。post

abstract class WidgetsBindingObserver {
  //頁面pop
  Future<bool> didPopRoute() => Future<bool>.value(false);
  //頁面push
  Future<bool> didPushRoute(String route) => Future<bool>.value(false);
  //系統窗口相關改變回調,如旋轉
  void didChangeMetrics() { }
  //文本縮放係數變化
  void didChangeTextScaleFactor() { }
  //系統亮度變化
  void didChangePlatformBrightness() { }
  //本地化語言變化
  void didChangeLocales(List<Locale> locale) { }
  //App生命週期變化
  void didChangeAppLifecycleState(AppLifecycleState state) { }
  //內存警告回調
  void didHaveMemoryPressure() { }
  //Accessibility相關特性回調
  void didChangeAccessibilityFeatures() {}
}
複製代碼

生命週期回調

  • resumed:可見的,並能響應用戶的輸入。
  • inactive:處在不活動狀態,沒法處理用戶響應。
  • paused:不可見並不能響應用戶的輸入,可是在後臺繼續活動中。

幀繪製回調

在組件渲染以後作一些與顯示安全相關的操做。ui

在 iOS 開發中,咱們能夠經過 dispatch_async(dispatch_get_main_queue(),^{…}) 方法,讓操做在下一個 RunLoop 執行;spa

在 Android 開發中,咱們能夠經過 View.post() 插入消息隊列,來保證在組件渲染後進行相關操做。code

  • 單次 Frame 繪製回調,經過 addPostFrameCallback 實現。它會在當前 Frame 繪製完成後進行進行回調,而且只會回調一次,若是要再次監聽則須要再設置一次。
WidgetsBinding.instance.addPostFrameCallback((_){
    print("單次Frame繪製回調");//只回調一次
});
複製代碼
  • 實時 Frame 繪製回調,則經過 addPersistentFrameCallback 實現。這個函數會在每次繪製 Frame 結束後進行回調,能夠用作 FPS 監測。
WidgetsBinding.instance.addPersistentFrameCallback((_){
  print("實時Frame繪製回調");//每幀都回調
});
複製代碼

總結

State的變化,則會觸發build,重建Widget。好比Widget A打開新的Widget B,Widget A的State發生變化。orm

相關文章
相關標籤/搜索