天天看點

Flutter 之 APP 生命周期

State 的生命周期,定義了 Widget 的加載到建構的全過程,可以利用其回調機制根據 Widget 的狀态選擇合适的時機做合适的事情。而 APP 的生命周期,則定義了 APP 從啟動到退出的全過程

如果想在對應的 APP 的生命周期事件中做相應的處理,比如 APP 從背景進入前台、從前台退到背景,或是在 UI 繪制完後做一些處理,則可以應用 WidgetsBindingObserver 類來實作

WidgetsBindingObserver 中的回調方法
// Accessibility 相關特性回調
void didChangeAccessibilityFeatures() { }

// App 生命周期改變回調
void didChangeAppLifecycleState(AppLifecycleState state) { }

// 本地化語言改變回調
void didChangeLocales(List<Locale> locale) { }

// 系統視窗相關改變回調
void didChangeMetrics() { }

// 系統亮度改變回調
void didChangePlatformBrightness() { }

// 文本縮放系數改變回調
void didChangeTextScaleFactor() { }

// 記憶體不足警告回調
void didHaveMemoryPressure() { }

// 頁面 pop
Future<bool> didPopRoute() => Future<bool>.value(false);

// 頁面 push
Future<bool> didPushRoute(String route) => Future<bool>.value(false);
           

要使用以上回調方法,隻需通過給 WidgetsBindingObserver 單例對象設定監聽器即可監聽相關回調方法

生命周期回調

didChangeAppLifecycleState 回調方法中,有一個參數類型為 AppLifecycleState 的枚舉類,這個枚舉類是 Flutter 對 App 生命周期狀态的封裝,常用的狀态包括 inactive、paused、resumed

  • inactive:處在不活動狀态,無法處理使用者響應
  • paused:不可見且不能響應使用者的輸入,但在背景繼續活動中
  • resumed:可見的,且能響應使用者的輸入
class AppLifecycleReactor extends StatefulWidget {
  const AppLifecycleReactor({ Key key }) : super(key: key);

  @override
  _AppLifecycleReactorState createState() => _AppLifecycleReactorState();
}

class _AppLifecycleReactorState extends State<AppLifecycleReactor> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);// 注冊監聽器
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);// 移除監聽器
    super.dispose();
  }

  AppLifecycleState _notification;

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    print("$state");
  }
}
           

可以試着切換下前背景,觀察下控制台輸出的 App 狀态

  • 從前台退到背景,控制台列印的 App 生命周期變化如下:

    AppLifecycleState.resumed->AppLifecycleState.inactive->AppLifecycleState.paused

  • 從背景切換回前台,控制台列印的 App 生命周期變化如下:

    AppLifecycleState.paused->AppLifecycleState.inactive->AppLifecycleState.resumed

Flutter 之 APP 生命周期

幀繪制回調

有時除了需要監聽 App 的生命周期回調外,還需要在元件完成渲染後做一些與顯示相關的其他處理,比如切換線程等,此時可以使用 WidgetsBinding 來實作

WidgetsBinding 提供了單次 Frame 繪制回調及實時 Frame 繪制回調兩種機制

  • 單次 Frame 繪制回調:通過 addPostFrameCallback 實作。在目前 Frame 繪制完後進行回調,且隻會回調一次,如果需要多次回調則需設定多次
WidgetsBindingObserver.instance.addPostFrameCallback((_){
    print("addPostFrameCallback 繪制回調"); // 隻回調一次
});
           
  • 實時 Frame 繪制回調:通過 addPersistentFrameCallback 實作。在每次繪制 Frame 結束後進行回調
WidgetsBindingObserver.instance.addPersistentFrameCallback((_){
    print("addPersistentFrameCallback 繪制回調"); // 每幀都回調
});