Flutter 3.13 之后如何监听 App 生命周期事件

news2024/9/17 21:03:49

在 Flutter 中,您可以监听多个生命周期事件来处理应用程序的不同状态,但今天我们将讨论 didChangeAppLifecycleState 事件。每当应用程序的生命周期状态发生变化时,就会触发此事件。可能的状态有 resumedinactivepauseddetachedhidden 。您可以使用 WidgetsBindingObserver mixin 监听此事件。

  1. resumed :在所有平台上,此状态表示应用程序处于具有输入焦点且可见的正在运行的应用程序的默认运行模式。
  2. inactive: 至少有一个应用程序视图可见,但都没有输入焦点。除此之外,应用程序运行正常。
  3. paused :应用程序当前对用户不可见,并且不响应用户输入。
  4. detached :应用程序仍由 Flutter 引擎托管,但脱离了任何主机视图。
  5. hidden :应用程序的所有视图都被隐藏,要么是因为应用程序即将暂停(在 iOS 和 Android 上),要么是因为应用程序已最小化或放置在不再可见的桌面上(在非 Web 桌面),或者正在(在 Web 上)不再可见的窗口或选项卡中运行。

通过在有状态小部件中实现这些生命周期状态,您可以响应不同的事件并相应地管理应用程序的状态。例如,您可以在应用程序进入后台时暂停或恢复某些操作,或者在小部件的依赖项发生变化时处理数据获取。

监听 Flutter 3.13 之前的 App 生命周期事件

在 Flutter 3.13 之前的版本中,您可以使用 WidgetsBindingObserver mixin 来处理应用程序生命周期事件。为此,您需要在 State 类中包含 WidgetsBindingObserver mixin 并重写 didChangeAppLifecycleState 方法。在此方法中,您可以访问应用程序的当前状态 ( AppLifecycleState ) 并相应地响应不同的应用程序生命周期事件。

class AppLifecyclePageOld extends StatefulWidget {
  const AppLifecyclePageOld({super.key});  
  State<AppLifecyclePageOld> createState() => _AppLifecyclePageOldState();
}

class _AppLifecyclePageOldState extends State<AppLifecyclePageOld>
    // Use the WidgetsBindingObserver mixin
    with WidgetsBindingObserver {

  
  void initState() {
    super.initState();

    // Register your State class as a binding observer
    WidgetsBinding.instance.addObserver(this);
  }

  
  void dispose() {
    // Unregister your State class as a binding observer
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  // Override the didChangeAppLifecycleState method and
  //Listen to the app lifecycle state changes
  
  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');

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

Flutter 3.13 后监听 App 生命周期事件的新方式

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

AppLifecycleListener 类提供了一种方便且替代的方法来监听 Flutter 中的应用程序生命周期事件。您可以使用 AppLifecycleListener 类来简化过程,而不是直接使用 WidgetsBindingObserver mixin。

要使用 AppLifecycleListener ,请创建该类的实例并传递您想要侦听的所需事件回调。这使您可以轻松处理特定的应用程序生命周期事件,而无需实现整个 WidgetsBindingObserver mixin。

通过使用 AppLifecycleListener ,您可以简化代码并使其更具可读性和可维护性,因为您只需要关注您感兴趣的特定事件。

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

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

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

  
  void initState() {
    super.initState();

    // Initialize the AppLifecycleListener class and pass callbacks
    _listener = AppLifecycleListener(
      onStateChange: _onStateChanged,
    );
  }

  
  void dispose() {
    // Do not forget to dispose the listener
    _listener.dispose();
    super.dispose();
  }

  // Listen to the app lifecycle state changes
  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');
  
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Placeholder(),
    );
  }
}

有什么区别?

旧方式与新方式非常相似,为了了解 AppLifecycleListener 类的主要好处,让我们看一下 Flutter 应用生命周期的状态机图:

该图说明了 Flutter 应用程序的各种状态以及它们之间可能的转换。在“旧”方法中,当重写 didChangeAppLifecycleState 方法时,您只能侦听特定的状态更改,例如应用程序何时转换到恢复状态。但是,您无法捕获有关状态之间转换的信息。例如,您无法确定应用程序是否从非活动状态或分离状态转换到恢复状态。

通过引入 AppLifecycleListener 类,您现在能够监听这些状态转换。这意味着您可以跟踪和响应应用程序经历的状态序列,从而更全面地了解其生命周期。

通过利用 AppLifecycleListener 类,您可以有效地捕获和处理状态之间的转换,从而可以更精确地控制和自定义应用程序的行为。

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

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

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

  
  void initState() {
    super.initState();

    // Pass all the callbacks for the transitions you want to listen to
    _listener = AppLifecycleListener(
      onDetach: _onDetach,
      onHide: _onHide,
      onInactive: _onInactive,
      onPause: _onPause,
      onRestart: _onRestart,
      onResume: _onResume,
      onShow: _onShow,
      onStateChange: _onStateChanged,
    );
  }

  
  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) {
    // Track state changes
    if (_currentState == 'onInactive' && state == AppLifecycleState.resumed) {
      //to do something...
    }
  }

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

另一个好处是你不需要实现 WidgetsBindingObserver mixin,这对于父类复杂的情况会非常方便。在这种情况下,您可能需要在父类中实现 WidgetsBindingObserver mixin 并在它们之间传递数据以处理生命周期事件,但现在,您可以在任何您想要的地方执行此操作!

取消 App 退出动作

您可以使用 AppLifecycleListener 类取消应用程序退出。AppLifecycleListener 中有一个回调函数 onExitRequested,该回调函数用于询问应用程序是否允许在可取消退出的情况下退出应用程序。例如,它可用于 MacOS 应用程序,当有未保存的更改时,用户会尝试关闭应用程序。

要取消退出请求,您需要从 onExitRequested 回调中返回 AppExitResponse.cancel 。否则,返回 AppExitResponse.exit 以允许应用程序退出:

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

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

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

  
  void initState() {
    super.initState();

    _listener = AppLifecycleListener(
      // Handle the onExitRequested callback
      onExitRequested: _onExitRequested,
    );
  }

  
  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;
  }

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

当用户单击应用程序中的关闭按钮时,将显示警报对话框。

结论

事实上, AppLifecycleListener 类引入了一种新的方法来监听应用程序生命周期状态,特别关注捕获这些状态之间的转换。 AppLifecycleListener 类的一个显着特性是包含 onExitRequested 回调。此回调简化了退出请求的处理,特别是在可以取消退出的情况下。

通过利用 AppLifecycleListener 类,您能够有效地监视和响应各个应用程序生命周期状态以及它们之间的转换。此外, onExitRequested 回调简化了退出请求的管理,允许根据应用的特定要求更顺利地取消或执行退出过程。

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


原文:https://blog.stackademic.com/how-to-listen-to-the-app-lifecycle-event-after-flutter-3-13-120a4ecf1453

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1533529.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

应急响应靶机训练-Web3题解

前言 接上文&#xff0c;应急响应靶机训练-Web3。 前来挑战&#xff01;应急响应靶机训练-Web3 题解 首先登录用户administrator 寻找隐藏用户 找到隐藏用户hack6618$ 然后去找apache的日志文件 分析得出两个IP地址 192.168.75.129 192.168.75.130 然后更换hack6618$的…

【前端】卡片渐变色阴影效果 旋转动画

【前端】卡片渐变色阴影效果 旋转动画 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>Breathing…

【2】华为交换机如何修改Web登录密码?

0x01 问题描述 如果忘记了Web登录密码或者希望修改Web登录密码&#xff0c;用户可以通过Console口、STelnet或Tenet等方式登录交换机后设置新的Web登录密码。 使用Telnet协议存在安全风险&#xff0c;建议使用Console囗或STelnet V2登录设备 0x02 问题解决 <HUAWEI> s…

HarmonyOS入门-环境及项目搭建

近来在学习HarmonyOS&#xff0c;虽然跟着入门项目敲了部分代码&#xff0c;但感觉还是有点云里雾里的&#xff0c;并且官方文档和视频课程只能说是一言难尽&#xff0c;所以打算通过写文章的方式记录下。 学习代码最好的方式是通过项目&#xff0c;官方提供的Demo还是挺不错的…

JAVA多线程之JMM

文章目录 1. Java内存模型2. 内存交互3. 三大特性3.1 可见性3.1.1 可见性问题3.1.2 原因3.1.3 解决方法 3.2 原子性3.3 有序性 4. 指令重排5. JMM 与 happens-before5.1 happens-before关系定义5.2 happens-before 关系 在继续学习JUC之前&#xff0c;我们现在这里介绍一下Java…

MySQL表的增删改查---多表查询和联合查询

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

眼科新视界:争议中的激光矫正手术

《眼科新视界&#xff1a;争议中的激光矫正手术》 一、眼科激光矫正手术&#xff1a;科技之光还是潜在风险&#xff1f; 1、激光矫正手术作为近年来眼科领域的热门技术&#xff0c;以其快速、安全、有效的特点吸引了众多近视、远视、散光等视力问题患者的关注。通过激光能量&…

怎么理解面向对象?一文带你全面理解

文章目录 1、类和对象&#xff08;1&#xff09;面向过程和面向对象初步认识&#xff08;2&#xff09;类的引入&#xff08;3&#xff09;类的定义&#xff08;4&#xff09;类的访问限定符及封装4.1 访问限定符4.2 封装 &#xff08;5&#xff09;类的作用域&#xff08;6&am…

虹科Pico汽车示波器 | 免拆诊断案例 | 2019 款东风悦达起亚K2车怠速起停系统工作异常

一、故障现象 一辆2019款东风悦达起亚K2车&#xff0c;搭载G4FG发动机&#xff0c;累计行驶里程约为9 400 km。车主反映&#xff0c;行驶至路口停车等红灯时&#xff0c;怠速起停&#xff08;ISG&#xff09;系统自动使发动机熄火&#xff0c;接着组合仪表提示“怠速起停已解除…

【MySQL】DDL的表操作详解:创建&查询&修改&删除(记得3点加上连接)

前言 大家好吖&#xff0c;欢迎来到 YY 滴MySQL系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C Linux的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的…

8 款AI 绘画生成器:从文本创建 AI 艺术图像

人工智能正在影响各行各业&#xff0c;近年来它对创意产业的影响越来越大。由于AI绘画生成器的可操作性&#xff0c;许多人有机会用自己的想法进行艺术创作——即使他们没有接受过系统的专业艺术教育。 最先进的人工智能绘画生成器可能会改变我们未来创作艺术的方式。使用 AI …

外贸新人必看!外贸入行

Erica今天整理了做外贸的基础步骤&#xff0c;以及一些注意事项&#xff0c;认真看。 常见外贸概念 1、传统外贸:就是国内企业为老外生产加工出口&#xff0c;以OEM为主(为品牌代工)&#xff0c;近年来由于国内企业创新能力提升&#xff0c;ODM(企业自主设计&#xff0c;贴老…

社区停车场管理系统由哪些部分组成?如何选择合适的社区停车场系统

在现代社区物业管理中&#xff0c;停车场的有效管理已成为提升居民满意度和物业服务质量的关键因素。随着居民对便捷生活的追求日益增长&#xff0c;一个高效、智能的停车场管理系统对于社区物业而言显得尤为重要和必要。它不仅能够提升社区内车辆管理的效率&#xff0c;保障居…

重大机遇,腾讯云优惠券免费领取入口整理,千元代金券一键搞定

腾讯云代金券领取渠道有哪些&#xff1f;腾讯云官网可以领取、官方媒体账号可以领取代金券、完成任务可以领取代金券&#xff0c;大家也可以在腾讯云百科蹲守代金券&#xff0c;因为腾讯云代金券领取渠道比较分散&#xff0c;腾讯云百科txybk.com专注汇总优惠代金券领取页面&am…

创建可引导的 macOS 安装器

你可以将外置驱动器或备用宗卷用作安装 Mac 操作系统的启动磁盘。 以下高级步骤主要适用于系统管理员以及其他熟悉在“终端”中输入命令的经验丰富的用户。 升级 macOS 或重新安装 macOS 不需要可引导安装器&#xff0c;但如果你要在多台电脑上安装 macOS&#xff0c;而又不…

武汉星起航:领航跨境电商,助力新手小白逐梦全球市场

在全球贸易日益频繁的今天&#xff0c;跨境电商已成为企业拓展国际市场的重要途径。作为跨境电商行业的领军者&#xff0c;武汉星起航电子商务有限公司自2017年起便深耕亚马逊自营店铺领域&#xff0c;积累了丰富的实战经验。公司在2020年的正式成立&#xff0c;其跨境电商业务…

最高一次性领取50万元!2024年全国各省市ITSS补贴汇总

根据ITSS官方数据表明&#xff0c;截止于3月21日&#xff0c;ITSS下证数据高达8000&#xff0c;全国各地的企业都有办理ITSS资质&#xff0c;足以见得ITSS在市场上的需求有多高&#xff0c;办理ITSS除了可以让企业自身的发展更好&#xff0c;部分地区的企业办理ITSS也是可以领取…

十二、MySQL 主从复制+高可用+读写分离

目录 一、mysqlkeeplived实现高可用LVS负载均衡 一、什么是高可用 二、为什么要用高可用 三、高可用的作用 四、keeplived 是什么&#xff1f;它用在哪里 五、安装mysql以及配置主从 六、keepalived安装 1、配置 单VIP 实现高可用 master上配置 2、backup上的配置 3、…

【感悟《剑指offer》典型编程题的极练之路】01数组篇!

​​​​​​​ ​​​​​​​ 个人主页&#xff1a;秋风起&#xff0c;再归来~ ​​​​​​​ 文章所属专栏&#xff1a;《剑指offer》典型编程题的极练之路 ​​​​​​​ ​​​​​​​ …

Android Audio相关

AudioManager AudioService的Bp端&#xff0c;调用AudioManager>AudioService&#xff08;代码实现&#xff09; AudioService 继承自IAudioService.Stub&#xff0c;为Bn端 AudioSystem AudioService功能实现都依赖于AudioSystem&#xff0c;AudioService通过AudioSys…