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得你们本身去发现。

相关文章
相关标签/搜索