Flutter的生命週期(交互)

1. 組件渲染

前面部分,已經介紹過了,組件的構建渲染=> 傳送門api

2. 先後臺交互

在咱們原生Android(或者IOS)開發中,不少是否要在對應的生命週期作一些事件,例如App從後臺進入前臺,從前臺退入後臺(或被遮蓋),以及須要在確保UI繪製後作一些處理,這在咱們原生開發中很容易作到,那麼在Flutter中須要怎麼去作呢?安全

很簡單,給WidgetsBinding設置Observeride

class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver{

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);//添加觀察者
  }

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

  @override
  void dispose() {
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);//銷燬
  }
  
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
複製代碼

經過以上代碼,咱們能夠看到只要給WidgetsBinding的單例對象添加WidgetsBindingObserver,而後此類粘合(with)WidgetsBindingObserver抽象類,在初始化State的時候給WidgetsBinding設置Observer爲當前類,並在銷燬的時候移除Observer,此時咱們的State就具有WidgetsBindingObserver的回調了。post

(關於with的做用讀者可自行搜索相關關鍵字mixinwith)。字體

咱們看看WidgetsBindingObserver中具體有哪些回調:ui

abstract class WidgetsBindingObserver {

   //路由彈出Future
  Future<bool> didPopRoute() => Future<bool>.value(false);

    //新的路由Future
  Future<bool> didPushRoute(String route) => Future<bool>.value(false);

    //系統窗口相關改變回調,例如旋轉
  void didChangeMetrics() { }

    //文字係數變化
  void didChangeTextScaleFactor() { }

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

    //生命週期變化
  void didChangeAppLifecycleState(AppLifecycleState state) { }

    //低內存回調
  void didHaveMemoryPressure() { }

    //當前系統改變了一些訪問性活動的回調
  void didChangeAccessibilityFeatures() {}
}
複製代碼

能夠看到,常見的屏幕、字體、語言等變化都會經過此類實現進行回調,這裏咱們關注生命週期的變化方法didChangeAppLifecycleStatethis

生命週期回調(didChangeAppLifecycleState)

void didChangeAppLifecycleState(AppLifecycleState state) { }spa

這個方法有一個參數類型爲AppLifecycleState的枚舉類,咱們能夠根據它的狀態來處理咱們的一些任務code

enum AppLifecycleState {
  resumed,
  inactive,
  paused,
  suspending,
}
複製代碼
  • resumed:應用可見並可響應用戶操做
  • inactive:用戶可見,但不可響應用戶操做
  • paused:已經暫停了,用戶不可見、不可操做
  • suspending:應用被掛起,此狀態IOS永遠不會回調

Flutter回調的生命週期與Android基本上差很少,這裏說一下回調比較特別的地方。server

以Android爲例,當咱們Activity建立的時候,流程是這樣的:

建立期:onCreate -> onStart -> onResume

進入後臺: onPause -> onStop

從後臺恢復:onRestart->onResume

而在Flutter中這整個流程是:

建立期: initState

進入後臺: inactive -> paused

從後臺恢復: inactive -> resumed

對比發現,在咱們頁面建立的時候不會觸發生命週期回調(didChangeAppLifecycleState),而在進入後臺和從後臺恢復的時候都會先調用inactive(可見,不可響應)而後調用paused(完全不可見)或者resumed(可見並可操做)。至於掛起(suspending)的回調,筆者暫時還不知道怎樣纔會觸發。

Tips:當生命週期可交互時(resumed)纔開始繪製Frame,生命週期變爲不可交互時(paused、suspending)會中止繪製Frame,這個後面分析Flutter啓動時會介紹。

3. 其它回調

有的時候咱們須要在Widget渲染以後作一些安全的操做,在Android中能夠經過View.post()插入消息隊列,這樣能夠保證在組件渲染後進行操做,那麼Flutter中有沒有這樣的API呢?固然有啦..

仍是咱們的WidgetsBinding

3.1 單次Frame繪製回調(addPostFrameCallback)
void initState() {
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((_){
    print("Frame has been rendered");
  });
}
複製代碼

經過addPostFrameCallback能夠作一些安全的操做,在有些時候是頗有用的,它會在當前Frame繪製完後進行回調,並只會回調一次,若是要再次監聽須要再設置。

3.2 實時Frame繪製回調(addPersistentFrameCallback)
WidgetsBinding.instance.addPersistentFrameCallback((_){
  print("Frame has been rendered");
});
複製代碼

這個api在每次繪製Frame結束後都會回調,咱們能夠利用它作一些幀率檢測。

這些都是比較經常使用的,更多有用好玩的api得你們本身去發現。

相關文章
相關標籤/搜索