Flutter应用中,有时候我们需要监听整个app的不同声明周期状态,然后做出相应的逻辑处理。
Flutter中的生命周期状态在window.dart 中有定义
enum AppLifecycleState {
/// The application is visible and responding to user input.
resumed,
/// The application is in an inactive state and is not receiving user input.
///
/// On iOS, this state corresponds to an app or the Flutter host view running
/// in the foreground inactive state. Apps transition to this state when in
/// a phone call, responding to a TouchID request, when entering the app
/// switcher or the control center, or when the UIViewController hosting the
/// Flutter app is transitioning.
///
/// On Android, this corresponds to an app or the Flutter host view running
/// in the foreground inactive state. Apps transition to this state when
/// another activity is focused, such as a split-screen app, a phone call,
/// a picture-in-picture app, a system dialog, or another window.
///
/// Apps in this state should assume that they may be [paused] at any time.
inactive,
/// The application is not currently visible to the user, not responding to
/// user input, and running in the background.
///
/// When the application is in this state, the engine will not call the
/// [Window.onBeginFrame] and [Window.onDrawFrame] callbacks.
///
/// Android apps in this state should assume that they may enter the
/// [suspending] state at any time.
paused,
/// The application will be suspended momentarily.
///
/// When the application is in this state, the engine will not call the
/// [Window.onBeginFrame] and [Window.onDrawFrame] callbacks.
///
/// On iOS, this state is currently unused.
suspending,
}
由以上源码可知,app一共有四种状态:
resumed
app当前可见,并且能响应用户的输入inactive
app当前在前台,但是不可响应用户的输入,即失去焦点paused
app当前在后台,不可响应用户的输入suspending
app当前处于短暂的暂停状态
Lifecycle Management步骤
- 自定义一个LifeCycleManager
class LifeCycleManager extends StatefulWidget {
final Widget child;
LifeCycleManager({Key key, this.child}) : super(key: key);
_LifeCycleManagerState createState() => _LifeCycleManagerState();
}
class _LifeCycleManagerState extends State<LifeCycleManager>
with WidgetsBindingObserver {
@override
void initState() {
WidgetsBinding.instance.addObserver(this);
super.initState();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
print('state = $state');
}
@override
Widget build(BuildContext context) {
return Container(
child: widget.child,
);
}
}
- 包装MaterialApp
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return LifeCycleManager(
child: MaterialApp(
title: 'Flutter Demo',
home: HomeView(),
),
);
}
}
- 制定一个可以暂停的Service基类,并添加判断当前Service服务是否关闭的方法
abstract class StoppableService {
bool _serviceStoped = false;
bool get serviceStopped => _serviceStoped;
@mustCallSuper
void stop() {
_serviceStoped = true;
}
@mustCallSuper
void start() {
_serviceStoped = false;
}
}
- 添加StoppableService的子类,比如有一个定位服务和一个在后台获取数据的service
class LocationService extends StoppableService {
@override
void start() {
super.start();
print('LocationService Started $serviceStopped');
}
@override
void stop() {
super.stop();
print('LocationService Stopped $serviceStopped');
}
}
class BackgroundFetchService extends StoppableService {
@override
void start() {
super.start();
// Start listeneing
print('BackgroundFetchService Started $serviceStopped');
}
@override
void stop() {
super.stop();
// stop listening
print('BackgroundFetchService Stopped $serviceStopped');
}
}
- 使用get_it来注册,关于get_it,我们在前文中介绍过 Flutter中的依赖注入——get_it
GetIt locator = GetIt.instance;
void setupLocator() {
locator.registerLazySingleton(() => LocationService());
locator.registerLazySingleton(() => BackgroundFetchService());
}
- 在LifeCycleManager的state对象中,管理所有的StoppableService,在相应的生命周期事件发生时,调用Service的相关方法
class _LifeCycleManagerState extends State<LifeCycleManager>
with WidgetsBindingObserver {
List<StoppableService> servicesToManage = [
locator<LocationService>(),
locator<BackgroundFetchService>(),
];
// Get all services
@override
Widget build(BuildContext context) {
return widget.child;
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
print("--" + state.toString());
servicesToManage.forEach((service) {
if (state == AppLifecycleState.resumed) {
service.start();
} else {
service.stop();
}
});
}
}
搞定!