如何监听 Flutter 3.13 版本以上的生命周期事件

如何监听 Flutter 3.13 版本以上的生命周期事件

1. 什么是 Flutter 应用的生命周期状态

Flutter 中,你可以收监听个生命周期事件以处理应用程序的不同状态,但是今天,我们将讨论 DidchangeApplifeCyclestate 事件。 每当应用程序的生命周期状态改变时,都会触发此事件。
其状态分别是 resumed, inactive, paused, detachedhidden,你可以使用混合类 WidgetsBindingObserver 以监听这个事件。

以下将对各种状态进行简单解说:

  1. resumed:恢复状态,即在所有平台上,此状态表明该应用程序正处于默认运行模式且具有输入焦点和可见的运行状态。

  2. Inactive:不激活状态,即至少可以看到该应用程序的一种视图,但没有一个输入焦点。

  3. paused:暂停状态,即当前对用户看不到该应用程序,也不响应用户输入。

  4. detached:脱离状态,即该应用程序仍由 Flutter 引擎托管,但与任何主视图脱离了。

  5. hidden:隐藏状态,即应用程序的所有视图都是隐藏的,要么是因为应用程序即将暂停(在iOS和Android上),要么是因为已将其最小化或放置在不再可见的桌面上(在非 Web 桌面),或在不再可见的窗口或选项卡中运行(在 web 上)。

通过在你的有状态小部件中实现这些生命周期状态,你就可以响应不同的事件并管理相应的应用程序的状态。 例如,当应用程序进入背景时,你可以暂停或恢复某些操作,或者在小部件的依赖性改变时处理和获取数据。

2. 监听 Flutter 3.13 版本之前的应用程序生命周期

Flutter 3.13 之前,你可以使用混合 WidgetsBindingObserver 类来处理应用的生命周期。你只需添加 WidgetsBindingObserver 混合类到你的状态类并重载 didChangeAppLifecycleState 方法即可。在此方法里,你将访问应用程序的当前状态 (AppLifecycleState) 和响应不同的应用程序生命周期,代码如下:

class AppLifecyclePageOld extends StatefulWidget {
  const AppLifecyclePageOld({super.key});

  @override
  State<AppLifecyclePageOld> createState() => _AppLifecyclePageOldState();
}

class _AppLifecyclePageOldState extends State<AppLifecyclePageOld>
    // 使用 WidgetsBindingObserver 混合
    with WidgetsBindingObserver {

  @override
  void initState() {
    super.initState();

    // 注册你的状态类以绑定一个观察者
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    // 将之前绑定的观察者类删除
    WidgetsBinding.instance.removeObserver(this);

    super.dispose();
  }

  // 重载 didChangeAppLifecycleState 方法
  // 以监听生命周期状态的变化
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);

    switch (state) {
      case AppLifecycleState.detached:
        _onDetached();
      case AppLifecycleState.resumed:
        _onResumed();
      case AppLifecycleState.inactive:
        _onInactive();
      case AppLifecycleState.hidden:
        _onHidden();
      case AppLifecycleState.paused:
        _onPaused();
    }
  }

  void _onDetached() => print('detached');

  void _onResumed() => print('resumed');

  void _onInactive() => print('inactive');

  void _onHidden() => print('hidden');

  void _onPaused() => print('paused');

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Placeholder(),
    );
  }
}

3. 在 Flutter 3.13 后使用新的方法以监听应用程序的生命周期事件

Flutter 3.13 之后,我们可以使用新的类 AppLifecycleListener 以监听应用程序的生命周期。

AppLifecycleListener 类提供了一个方便的方式以监听 Flutter 应用的生命周期事件,对比起直接使用 WidgetsBindingObserver 混合的方法,你可以使用 AppLifecycleListener 类以简单的方式完成相关操作。

使用 AppLifecycleListener 可让你的代码更精简且易于阅读和维护,你只需要关注你感兴趣的事件即可:

class AppLifecyclePage extends StatefulWidget {
  const AppLifecyclePage({super.key});

  @override
  State<AppLifecyclePage> createState() => _AppLifecyclePageState();
}

class _AppLifecyclePageState extends State<AppLifecyclePage> {
  late final AppLifecycleListener _listener;

  @override
  void initState() {
    super.initState();

    // 初始化 AppLifecycleListener 类并设置其回调
    _listener = AppLifecycleListener(
      onStateChange: _onStateChanged,
    );
  }

  @override
  void dispose() {
    // 不要忘记释放监听对象
    _listener.dispose();

    super.dispose();
  }

  // 监听应用程序的生命周期变化
  void _onStateChanged(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.detached:
        _onDetached();
      case AppLifecycleState.resumed:
        _onResumed();
      case AppLifecycleState.inactive:
        _onInactive();
      case AppLifecycleState.hidden:
        _onHidden();
      case AppLifecycleState.paused:
        _onPaused();
    }
  }

  void _onDetached() => print('detached');

  void _onResumed() => print('resumed');

  void _onInactive() => print('inactive');

  void _onHidden() => print('hidden');

  void _onPaused() => print('paused');

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Placeholder(),
    );
  }
}

4. 有什么不同?

旧方法与新方法很相似,要理解使用 AppLifecycleListener 类的优势,让我们先来看看下面这张 Flutter 应用的生命周期流程图:

上图中说明了 Flutter 应用里几种状态的和它们之类的关系。在旧方法中,当重载 didChangeAppLifecycleState 方法时,就只能监听到指定的状态变化,如应用改变到恢复状态,但你却不能了解到其具体变化的过程,如你并不知道应用此时是从哪一个状态转变到恢复状态的。

而使用 AppLifecycleListener 类的话,你就可以知道这些转变的过程,也就是说你可以追踪和响应到一连串的状态变化从而对其生命周期有更全面的了解。

同时通过使用 AppLifecycleListener 类,你也可以更有效地控制在应用程序里的自定义操作和行为,能有效地处理状态转换中的变化。

以下是示例代码:

class AppLifecyclePage extends StatefulWidget {
  const AppLifecyclePage({super.key});

  @override
  State<AppLifecyclePage> createState() => _AppLifecyclePageState();
}

class _AppLifecyclePageState extends State<AppLifecyclePage> {
  late final AppLifecycleListener _listener;
  String _currentState = '';

  @override
  void initState() {
    super.initState();

    // 你可以实现所有的回调函数并记录其变化的过程
    _listener = AppLifecycleListener(
      onDetach: _onDetach,
      onHide: _onHide,
      onInactive: _onInactive,
      onPause: _onPause,
      onRestart: _onRestart,
      onResume: _onResume,
      onShow: _onShow,
      onStateChange: _onStateChanged,
    );
  }

  @override
  void dispose() {
    _listener.dispose();

    super.dispose();
  }

  void _onDetach() {
    print('onDetach');
    _currentState = 'onDetach';
  }

  void _onHide() {
    print('onHide');
    _currentState = 'onHide';
  }

  void _onInactive() {
    print('onInactive');
    _currentState = 'onInactive';
  }

  void _onPause() {
    print('onPause');
    _currentState = 'onPause';
  }

  void _onRestart() {
    print('onRestart');
    _currentState = 'onRestart';
  }

  void _onResume() {
    print('onResume');
    _currentState = 'onResume';
  }

  void _onStateChanged(AppLifecycleState state) {
    // 追踪状态的变化
    if (_currentState == 'onInactive' && state == AppLifecycleState.resumed) {
      //其他逻辑...
    }
  }

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Placeholder(),
    );
  }
}

另一个好处是你并不需要实现 WidgetsBindingObserver 混合,这对于拥有复杂父类的情况是非常好和方便的做法。在这种情况下,你可能需要在父类去实现 WidgetsBindingObserver 混合,然后在它们之类传递数据以处理生命周期事件,但现在,你可以在任何地方使用它!

5. 取消关闭应用的操作

你还可以使用 AppLifecycleListener 类来取消关闭应用的操作。在 AppLifecycleListener 里有一个回调事件叫 onExitRequested, 这个回调是用来询问应用程序关闭时是否允许其继续的,也就是说你可以控制其不让应用关闭。这通常用于在桌面应用,如在 MacOS 里的应用,当用户点击了左上角的关闭应用按钮时,但并未保存数据,就可以给用户提示不要关闭应用先。

要使用取消关闭这功能,你需要在 onExitRequested 回调中反回 AppExitResponse.cancel,而如果返回 AppExitResponse.exit 就代表允许关闭:

class AppLifecyclePage extends StatefulWidget {
  const AppLifecyclePage({super.key});

  @override
  State<AppLifecyclePage> createState() => _AppLifecyclePageState();
}

class _AppLifecyclePageState extends State<AppLifecyclePage> {
  late final AppLifecycleListener _listener;

  @override
  void initState() {
    super.initState();

    _listener = AppLifecycleListener(
      // 处理 onExitRequested 回调
      onExitRequested: _onExitRequested,
    );
  }

  @override
  void dispose() {
    _listener.dispose();

    super.dispose();
  }

  // 询问用户是否要关闭应用,如果用户不要关闭则返回 AppExitResponse.cancel
  //  否则就返回 AppExitResponse.exit.
  Future<AppExitResponse> _onExitRequested() async {
    final response = await showDialog<AppExitResponse>(
      context: context,
      barrierDismissible: false,
      builder: (context) => AlertDialog.adaptive(
        title: const Text('您要退出此应用吗?'),
        content: const Text('所有未保存的数据变会丢失!'),
        actions: [
          TextButton(
            child: const Text('取消'),
            onPressed: () {
              Navigator.of(context).pop(AppExitResponse.cancel);
            },
          ),
          TextButton(
            child: const Text('确定'),
            onPressed: () {
              Navigator.of(context).pop(AppExitResponse.exit);
            },
          ),
        ],
      ),
    );

    return response ?? AppExitResponse.exit;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('应用程序生命周期演示'),
      ),
      body: Center(
        child: Text(
          '退出应用',
          style: Theme.of(context).textTheme.displayLarge,
        ),
      ),
    );
  }
}

当用户点击关闭按钮时,提示对话框将会弹出。

6. 总结

AppLifecycleListener 类引入了一种监听应用程序生命周期的新方法,让我们可着眼于捕获这些状态之间的过渡情况。值得注意的是,通过使用 AppLifecycleListener 里的 onExitRequested 回调,还可以处理应用关闭时的请求,以做到取消关闭的效果。

这种简化的处理退出请求的方法减轻了管理此类方案的负担,并增强了应用程序生命周期管理的整体控制和灵活性。

代码部落

免费订阅以得到最新文章发布的通知

请放心,这个绝对不会是垃圾邮件
而且您随时也可以取消的

版权声明:
作者:winson
链接:https://www.coderblog.cc/2024/07/how-to-listen-the-app-lifecycle-events-after-flutter-3-13/
来源:代码部落中文站
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭
目 录