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}); @override
State<AppLifecyclePageOld> createState() => _AppLifecyclePageOldState();
}
class _AppLifecyclePageOldState extends State<AppLifecyclePageOld>
// Use the WidgetsBindingObserver mixin
with WidgetsBindingObserver {
@override
void initState() {
super.initState();
// Register your State class as a binding observer
WidgetsBinding.instance.addObserver(this);
}
@override
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
@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(),
);
}
}
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});
@override
State<AppLifecyclePage> createState() => _AppLifecyclePageState();
}
class _AppLifecyclePageState extends State<AppLifecyclePage> {
late final AppLifecycleListener _listener;
@override
void initState() {
super.initState();
// Initialize the AppLifecycleListener class and pass callbacks
_listener = AppLifecycleListener(
onStateChange: _onStateChanged,
);
}
@override
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');
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Placeholder(),
);
}
}
有什么区别?
旧方式与新方式非常相似,为了了解 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();
// 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,
);
}
@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) {
// Track state changes
if (_currentState == 'onInactive' && state == AppLifecycleState.resumed) {
//to do something...
}
}
@override
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});
@override
State<AppLifecyclePage> createState() => _AppLifecyclePageState();
}
class _AppLifecyclePageState extends State<AppLifecyclePage> {
late final AppLifecycleListener _listener;
@override
void initState() {
super.initState();
_listener = AppLifecycleListener(
// Handle the onExitRequested callback
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('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