Flutter 3.13 之后如何监听 App 生命周期事件
在 Flutter 中,您可以监听多个生命周期事件来处理应用程序的不同状态,但今天我们将讨论 didChangeAppLifecycleState 事件。每当应用程序的生命周期状态发生变化时,就会触发此事件。可能的状态有 resumed 、 inactive 、 paused 、 detached 和 hidden 。您可以使用 WidgetsBindingObserver mixin 监听此事件。
resumed:在所有平台上,此状态表示应用程序处于具有输入焦点且可见的正在运行的应用程序的默认运行模式。inactive: 至少有一个应用程序视图可见,但都没有输入焦点。除此之外,应用程序运行正常。paused:应用程序当前对用户不可见,并且不响应用户输入。detached:应用程序仍由 Flutter 引擎托管,但脱离了任何主机视图。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 mixinwith WidgetsBindingObserver {void initState() {super.initState();// Register your State class as a binding observerWidgetsBinding.instance.addObserver(this);}void dispose() {// Unregister your State class as a binding observerWidgetsBinding.instance.removeObserver(this);super.dispose();}// Override the didChangeAppLifecycleState method and//Listen to the app lifecycle state changesvoid 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 changesvoid _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 changesif (_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 callbackonExitRequested: _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
相关文章:
Flutter 3.13 之后如何监听 App 生命周期事件
在 Flutter 中,您可以监听多个生命周期事件来处理应用程序的不同状态,但今天我们将讨论 didChangeAppLifecycleState 事件。每当应用程序的生命周期状态发生变化时,就会触发此事件。可能的状态有 resumed 、 inactive 、 paused 、 detached …...
基于docker创建深度学习开发环境
基于docker创建深度学习开发环境 记录几个链接 第一步:配置docker环境,此处大把教程,不再赘述第二步:拉取nvidia做好的cuda和cudnn镜像: docker pull nvcr.io/nvidia/cuda:12.2.0-devel-ubuntu20.04如果有其他需求&a…...
Linux系统——硬件命令
目录 一.网卡带宽 1.查看网卡速率——ethtool 网卡名 2.查看mac地址——ethtool -P 网卡名 二、内存相关 1.显示系统中内存使用情况——free -h 2.显示内存模块的详细信息——dmidecode -t memory 三、CPU相关 1.查看CPU架构信息——lscpu 2.性能模式 四、其他硬件命…...
R语言Meta分析核心技术:回归诊断与模型验证
R语言作为一种强大的统计分析和绘图语言,在科研领域发挥着日益重要的作用。其中,Meta分析作为一种整合多个独立研究结果的统计方法,在R语言中得到了广泛的应用。通过R语言进行Meta分析,研究者能够更为准确、全面地评估某一研究问题…...
动态规划Dynamic Programming
上篇文章我们简单入门了动态规划(一般都是简单的上楼梯,分析数据等问题)点我跳转,今天给大家带来的是路径问题,相对于上一篇在一维中摸爬滚打,这次就要上升到二维解决问题,但都用的是动态规划思…...
详解机器学习概念、算法
目录 前言 一、常见的机器学习算法 二、监督学习和非监督学习 三、常见的机器学习概念解释 四、深度学习与机器学习的区别 基于Python 和 TensorFlow 深度学习框架实现简单的多层感知机(MLP)神经网络的示例代码: 欢迎三连哦! 前言…...
语音转文字——sherpa ncnn语音识别离线部署C++实现
简介 Sherpa是一个中文语音识别的项目,使用了PyTorch 进行语音识别模型的训练,然后训练好的模型导出成 torchscript 格式,以便在 C 环境中进行推理。尽管 PyTorch 在 CPU 和 GPU 上有良好的支持,但它可能对资源的要求较高&#x…...
第1篇:Mysql数据库表结构导出字段到Excel(一个sheet中)
package com.xx.util;import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.sql.*; import java.io.*;public class DatabaseToExcel {public static void main(String[] args) throws Exception {// 数据库连接配置String u…...
Request请求参数----中文乱码问题
一: GET POST获取请求参数: 在处理为什么会出现中文乱码的情况之前, 首先我们要直到GET 以及 POST两种获取请求参数的不同 1>POST POST获取请求参数是通过输入流getReader来进行获取的, 通过字符输入流来获取响应的请求参数, 并且在解码的时候, 默认的情况是 ISO_885…...
labelImg安装方法
labelImg安装方法(简单方法) - 知乎 (zhihu.com) 1. lableImg下载 git clone https://github.com/tzutalin/labelImg.git 2. 制作lableImg所需的"condapython"环境(conda需要先安装,最好再设置下下载源) 打开Anaconda Prompt对话框 # 创建环境 conda create -n …...
吴恩达2022机器学习专项课程(一) 3.6 可视化样例
问题预览 1.本节课主要讲的是什么? 2.不同的w和b,如何影响线性回归和等高线图? 3.一般用哪种方式,可以找到最佳的w和b? 解读 1.课程内容 设置不同的w和b,观察模型拟合数据,成本函数J的等高线…...
C#入门及进阶教程|Windows窗体属性及方法
1.Windows窗体 窗体本身是一个对象,对应于System.Windows.Forms名称空间的Form类。它有自己的属性、方法和事件,用于控制窗体的外观和行为。窗体又是各种控件的容器,用于容纳各种窗体控件。如果想生成窗体,必须从Form类派生出自己…...
34-Java传输对象模式 ( Transfer Object Pattern )
Java传输对象模式 实现范例 传输对象模式(Transfer Object Pattern)用于从客户端向服务器一次性传递带有多个属性的数据传输对象也被称为数值对象,没有任何行为传输对象是一个具有 getter/setter 方法的简单的 POJO 类,它是可序列…...
flutter实现视频播放器,可根据指定视频地址播放、设置声音,进度条拖动,下载等
需要装依赖: gallery_saver: ^2.3.2video_player: ^2.8.3 AndroidManifest.xml <uses-permission android:name"android.permission.INTERNET"/> 实现代码 import dart:async; import dart:io;import package:flutter/material.dart; import pa…...
微服务(基础篇-001-介绍、Eureka)
目录 认识微服务(1) 服务架构演变(1.1) 单体架构(1.1.1) 分布式架构(1.1.2) 微服务(1.1.3) 微服务结构 微服务技术对比 企业需求 SpringCloud(1.2) …...
mac 解决随机出现的蓝色框
macbookair为什么打字的时候按空格键会出现蓝色框? - 知乎...
深入理解与使用go之函数与方法--使用
深入理解与使用go之函数与方法–理解与使用 文章目录 引子函数与方法分类函数函数入参普通参数可变参数默认值返回命名不带命名带命名讨论init 函数defer 函数方法值接收指针接收构造函数引子 在 Go 语言中,函数被视为一等公民(First-Class Citizens),这意味着函数可以像其…...
【QT问题】 Qt信号函数如果重名,调用怎么处理
问题描述: 在调用某个类的信号函数的时候,出现信号函数名字相同,参数不同的情况,但是Qt在链接信号槽的时候,又不需要指明信号函数参数,此时就会出现无法分辨的情况。 例如:QComboBox的信号 Q_…...
登山小分队(dfs,模拟)
原题链接: 题目描述 Foxity和他的好友们相约去爬山,但是他们每个人都来到了不同的山脚下。整个山的结构类似一棵 "树",有很多的观光节点通过一条条山道连接起来。 在图论中,树是一种无向图,其中任意两个顶…...
Luminar Neo:重塑图像编辑新纪元,Mac与Win双平台畅享创意之旅
在数字时代的浪潮中,图像编辑软件已成为摄影师和设计师们不可或缺的创作工具。Luminar Neo,作为一款专为Mac与Windows双平台打造的图像编辑软件,正以其卓越的性能和创新的编辑功能,引领着图像编辑的新潮流。 Luminar Neo不仅继承…...
如何用ESP32打造你的个性化智能网络收音机:YoRadio完全指南
如何用ESP32打造你的个性化智能网络收音机:YoRadio完全指南 【免费下载链接】yoradio Web-radio based on ESP32-audioI2S library 项目地址: https://gitcode.com/GitHub_Trending/yo/yoradio 你是否厌倦了传统收音机有限的功能和单调的操作界面?…...
vant-weapp版本升级技术指南:从0.x到最新版的平滑迁移方案
vant-weapp版本升级技术指南:从0.x到最新版的平滑迁移方案 【免费下载链接】vant-weapp 轻量、可靠的小程序 UI 组件库 项目地址: https://gitcode.com/gh_mirrors/va/vant-weapp 引言 在小程序开发过程中,组件库的版本升级是一项常见但具有挑战…...
开发提效利器:基于快马平台构建可复用的mcp工具连接池
最近在开发AI应用时,经常需要连接各种外部服务,每次都要重复写一堆适配代码,特别浪费时间。后来发现用MCP协议统一管理这些连接可以大幅提升效率,于是在InsCode(快马)平台上搭建了一个可复用的MCP工具连接池模板,现在分…...
解决Obsidian图片管理痛点:打造稳定可靠的本地图片库
解决Obsidian图片管理痛点:打造稳定可靠的本地图片库 【免费下载链接】obsidian-local-images-plus This repo is a reincarnation of obsidian-local-images plugin which main aim was downloading images in md notes to local storage. 项目地址: https://git…...
胡桃工具箱:原神玩家的全能桌面助手与数据管理神器
胡桃工具箱:原神玩家的全能桌面助手与数据管理神器 【免费下载链接】Snap.Hutao 实用的开源多功能原神工具箱 🧰 / Multifunctional Open-Source Genshin Impact Toolkit 🧰 项目地址: https://gitcode.com/GitHub_Trending/sn/Snap.Hutao …...
Baichuan-M2-32B-GPTQ-Int4医疗推理模型Git部署实战:5步完成环境搭建
Baichuan-M2-32B-GPTQ-Int4医疗推理模型Git部署实战:5步完成环境搭建 1. 为什么选择Git方式部署这个医疗模型 最近在医疗AI项目中频繁遇到一个实际问题:团队成员需要快速复现相同的推理环境,但每次手动下载模型权重、配置依赖、调整参数都容…...
告别手动写单测:实测通义灵码2.0的单元测试生成到底有多强?
通义灵码2.0单元测试生成实战:从人工到AI的效能革命 单元测试作为保障代码质量的第一道防线,其重要性不言而喻。但现实中,开发者往往需要投入大量时间编写和维护测试用例。我曾在一个电商项目中统计过,团队40%的研发时间消耗在单元…...
Kubernetes集群中containerd运行时集成Harbor与阿里云私有仓库及镜像加速器的实战配置指南
1. 为什么需要集成多种镜像仓库? 在Kubernetes生产环境中,容器镜像的来源往往不是单一的。你可能需要从多个渠道获取镜像:企业内部搭建的Harbor私有仓库存放核心业务镜像,阿里云私有仓库托管第三方组件,公共镜像加速器…...
FlowState Lab生成复杂分形图案:Mandelbrot集扩展可视化
FlowState Lab生成复杂分形图案:Mandelbrot集扩展可视化 1. 当数学艺术遇上AI生成 分形几何一直被誉为"大自然的几何学",而Mandelbrot集则是其中最著名的代表。传统生成方法需要大量计算资源,往往在细节表现和生成效率之间难以平…...
通义千问1.5-1.8B-Chat-GPTQ-Int4数据库课程设计助手:ER图生成与SQL优化
通义千问1.5-1.8B-Chat-GPTQ-Int4数据库课程设计助手:ER图生成与SQL优化 对于计算机相关专业的学生来说,数据库课程设计是个绕不过去的坎。从需求分析到ER图绘制,再到建表写SQL,最后还要面对性能优化,每一步都让不少同…...
