备注:Flutter v3.13 版本以下推荐使用;以上使用官方实现 AppLifecycleListener;
一、需求来源
项目中多页面需要同时监听 AppLifecycleState 根据状态实现不同的业务逻辑;尝试多种实现,使用起来比较麻烦,为了开发效率,随封装一个。代码不复杂,核心在于极简的封装方法。
效果如下:
//进入后台
[log] 2024-05-31 10:50:53.133135 AppTabPage inactive
[log] 2024-05-31 10:50:53.134143 AppLifecycleStateObserverDemo inactive
[log] 2024-05-31 10:50:53.871600 AppTabPage hidden
[log] 2024-05-31 10:50:53.871889 AppLifecycleStateObserverDemo hidden
[log] 2024-05-31 10:50:53.872113 AppTabPage paused
[log] 2024-05-31 10:50:53.872335 AppLifecycleStateObserverDemo paused
//进入前台
[log] 2024-05-31 10:51:06.348528 AppTabPage hidden
[log] 2024-05-31 10:51:06.348764 AppLifecycleStateObserverDemo hidden
[log] 2024-05-31 10:51:06.348977 AppTabPage inactive
[log] 2024-05-31 10:51:06.349141 AppLifecycleStateObserverDemo inactive
[log] 2024-05-31 10:51:06.625449 AppTabPage resumed
[log] 2024-05-31 10:51:06.626024 AppLifecycleStateObserverDemo resumed
//上划杀掉 app
[log] 2024-05-31 10:51:33.060508 AppTabPage detached
[log] 2024-05-31 10:51:33.060692 AppLifecycleStateObserverDemo detached
// AppTabPage 为主页面;
// AppLifecycleStateObserverDemo 为特定业务界面;
二、使用示例
import 'package:flutter/material.dart';
import 'package:flutter_templet_project/util/AppLifecycleObserver.dart';
import 'package:flutter_templet_project/util/debug_log.dart';
class AppLifecycleStateObserverDemo extends StatefulWidget {
AppLifecycleStateObserverDemo({
super.key,
this.title
});
final String? title;
@override
State<AppLifecycleStateObserverDemo> createState() => _AppLifecycleStateObserverDemoState();
}
class _AppLifecycleStateObserverDemoState extends State<AppLifecycleStateObserverDemo> with
AppLifecycleObserverMixin {
final _scrollController = ScrollController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title ?? "$widget"),
actions: ['done',].map((e) => TextButton(
child: Text(e,
style: TextStyle(color: Colors.white),
),
onPressed: () => debugPrint(e),)
).toList(),
),
body: buildBody(),
);
}
buildBody() {
return Scrollbar(
controller: _scrollController,
child: SingleChildScrollView(
controller: _scrollController,
child: Column(
children: [
Text("$widget"),
],
),
),
);
}
/*************** AppLifecycleObserverMixin ***************/
@override
void onAppLifecycleStateChanged(AppLifecycleState state) {
ddlog("$widget onAppLifecycleStateChanged $state");
}
}
三、源码
1、AppLifecycleObserver 源码
/// app 前后台生命周期函数监听
class AppLifecycleObserver extends WidgetsBindingObserver{
AppLifecycleObserver({
required this.onStateChanged,
});
final ValueChanged<AppLifecycleState> onStateChanged;
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
onStateChanged(state);
}
}
2、AppLifecycleObserverMixin 源码
/// app 前后台生命周期函数混入封装
mixin AppLifecycleObserverMixin<T extends StatefulWidget> on State<T>{
late final _lifecycleEvent = AppLifecycleObserver(
onStateChanged: onAppLifecycleStateChanged,
);
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(_lifecycleEvent);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(_lifecycleEvent);
super.dispose();
}
void onAppLifecycleStateChanged(AppLifecycleState state) {
throw UnimplementedError("❌: $this 未实现 onAppLifecycleStateChanged");
// debugPrint('onStateChanged didChangeAppLifecycleState state');
}
}
四、总结
1、Flutter 3.13 之后官方实现了一个 AppLifecycleListener
使用效果和 AppLifecycleObserverMixin 相同,基于官方优先原则(未来维护性考虑),建议大家使用官方 AppLifecycleListener实现功能。
class AppLifecycleListener with WidgetsBindingObserver, Diagnosticable {
/// Creates an [AppLifecycleListener].
AppLifecycleListener({
WidgetsBinding? binding,
this.onResume,
this.onInactive,
this.onHide,
this.onShow,
this.onPause,
this.onRestart,
this.onDetach,
this.onExitRequested,
this.onStateChange,
}) : binding = binding ?? WidgetsBinding.instance,
_lifecycleState = (binding ?? WidgetsBinding.instance).lifecycleState {
this.binding.addObserver(this);
}
。。。