应用生命周期 :
Flutter 应用生命周期状态枚举 : 该枚举中四个生命周期状态 , 源码注释中详细说明了每个状态的用法 ;
/// States that an application can be in.
///
/// The values below describe notifications from the operating system.
/// Applications should not expect to always receive all possible
/// notifications. For example, if the users pulls out the battery from the
/// device, no notification will be sent before the application is suddenly
/// terminated, along with the rest of the operating system.
///
/// See also:
///
/// * [WidgetsBindingObserver], for a mechanism to observe the lifecycle state
/// from the widgets layer.
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.
paused,
/// The application is still hosted on a flutter engine but is detached from
/// any host views.
///
/// When the application is in this state, the engine is running without
/// a view. It can either be in the progress of attaching a view when engine
/// was first initializes, or after the view being destroyed due to a Navigator
/// pop.
detached,
}
监听 Flutter 应用生命周期 , 需要在页面 StatefulWidget 的 initState 页面生命周期函数中注册 WidgetsBindingObserver 观察者 ;
@override
void initState() {
super.initState();
/// 如果想要监听应用生命周期 , 要先绑定观察者 ,
/// 绑定完成后 , 如果应用生命周期发生了变化 ,
/// 就会回调 didChangeAppLifecycleState 方法 ;
WidgetsBinding.instance.addObserver(this);
}
注册了 WidgetsBindingObserver 观察者之后 , 在应用生命周期改变时 , 就会回调 WidgetsBindingObserver 类的 didChangeAppLifecycleState 方法 , 其 AppLifecycleState state 参数就是当前的应用生命周期状态 ;
/// 当应用生命周期发生变化时 , 会回调该方法
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
print("当前的应用生命周期状态 : ${state}");
if(state == AppLifecycleState.paused){
print("应用进入后台 paused");
}else if(state == AppLifecycleState.resumed){
print("应用进入前台 resumed");
}else if(state == AppLifecycleState.inactive){
// 应用进入非活动状态 , 如来了个电话 , 电话应用进入前台
// 本应用进入该状态
print("应用进入非活动状态 inactive");
}else if(state == AppLifecycleState.detached){
// 应用程序仍然在 Flutter 引擎上运行 , 但是与宿主 View 组件分离
print("应用进入 detached 状态 detached");
}
}
在 StatefulWidget 页面销毁时需要移除该 WidgetsBindingObserver 观察者 ;
/// 移出组件中注册的观察者
@override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);
}
完整代码示例 :
import 'package:flutter/material.dart';
class AppLifeCyclePage extends StatefulWidget {
@override
_AppLifeCyclePageState createState() => _AppLifeCyclePageState();
}
class _AppLifeCyclePageState extends State<AppLifeCyclePage> with WidgetsBindingObserver {
@override
void initState() {
super.initState();
/// 如果想要监听应用生命周期 , 要先绑定观察者 ,
/// 绑定完成后 , 如果应用生命周期发生了变化 ,
/// 就会回调 didChangeAppLifecycleState 方法 ;
WidgetsBinding.instance.addObserver(this);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// 标题
title: Text("应用生命周期"),
// 返回按钮
leading: BackButton(),
),
body: Container(
// 居中设置
alignment: Alignment.center,
child: Text("应用生命周期"),
),
);
}
/// 移出组件中注册的观察者
@override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);
}
/// 当应用生命周期发生变化时 , 会回调该方法
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
print("当前的应用生命周期状态 : ${state}");
if(state == AppLifecycleState.paused){
print("应用进入后台 paused");
}else if(state == AppLifecycleState.resumed){
print("应用进入前台 resumed");
}else if(state == AppLifecycleState.inactive){
// 应用进入非活动状态 , 如来了个电话 , 电话应用进入前台
// 本应用进入该状态
print("应用进入非活动状态 inactive");
}else if(state == AppLifecycleState.detached){
// 应用程序仍然在 Flutter 引擎上运行 , 但是与宿主 View 组件分离
print("应用进入 detached 状态 detached");
}
}
}
运行效果 :
进入界面 : 进入界面后 , 由于还没有注册 WidgetsBindingObserver , 因此不打印日志 , 等界面加载完毕后 , 进行各种操作 ( 如按下 Home 键 , 按下回退键 , 按下菜单键 ) 时才打印日志 ;
按下菜单键 :
I/flutter (30370): 当前的应用生命周期状态 : AppLifecycleState.inactive
I/flutter (30370): 应用进入非活动状态 inactive
D/FlutterView(30370): Detaching from a FlutterEngine: io.flutter.embedding.engine.FlutterEngine@9d12774
I/flutter (30370): 当前的应用生命周期状态 : AppLifecycleState.paused
I/flutter (30370): 应用进入后台 paused
再次点击回到应用界面 :
I/flutter (30370): 当前的应用生命周期状态 : AppLifecycleState.resumed
I/flutter (30370): 应用进入前台 resumed
D/FlutterView(30370): Attaching to a FlutterEngine: io.flutter.embedding.engine.FlutterEngine@9d12774
完整日志 :
# 按下菜单键
I/flutter (30370): 当前的应用生命周期状态 : AppLifecycleState.inactive
I/flutter (30370): 应用进入非活动状态 inactive
D/FlutterView(30370): Detaching from a FlutterEngine: io.flutter.embedding.engine.FlutterEngine@9d12774
I/flutter (30370): 当前的应用生命周期状态 : AppLifecycleState.paused
I/flutter (30370): 应用进入后台 paused
# 返回界面
I/flutter (30370): 当前的应用生命周期状态 : AppLifecycleState.resumed
I/flutter (30370): 应用进入前台 resumed
D/FlutterView(30370): Attaching to a FlutterEngine: io.flutter.embedding.engine.FlutterEngine@9d12774
参考资料 :
博客源码下载 :