如何使用 Flutter 处理应用程序生命周期(在 Android 和 iOS 上)?

Posted

技术标签:

【中文标题】如何使用 Flutter 处理应用程序生命周期(在 Android 和 iOS 上)?【英文标题】:How to handle app lifecycle with Flutter (on Android and iOS)? 【发布时间】:2018-10-12 09:12:38 【问题描述】:

Flutter 应用中有 Activity 生命周期方法吗?

喜欢:

onCreate()
onResume()
onDestroy()

或者:

viewDidload()
viewWillAppear()

使用 Flutter 制作应用时如何处理应用生命周期?

【问题讨论】:

【参考方案1】:

当系统将应用程序置于后台或将应用程序返回到前台时,会调用一个名为didChangeAppLifecycleState的方法。

Example with widgets:

  class _AppLifecycleReactorState extends State<AppLifecycleReactor> with WidgetsBindingObserver 
  @override
  void initState() 
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  

  @override
  void dispose() 
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  

  AppLifecycleState _notification;

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) 
    setState(()  _notification = state; );
  

  @override
  Widget build(BuildContext context) 
    return new Text('Last notification: $_notification');
  

还有 CONSTANTS 可以知道应用程序可以处于的状态,例如:

    无效 暂停 已恢复 暂停

这些常量的用法将是常量的值,例如:

const AppLifecycleState(state)

【讨论】:

如何完成上一个活动?像 Splash 一样登录 @DeepakKanyan 我认为这是另一个问题,与此问题无关,您可以提出新问题,然后参考我,如果可以,我会提供帮助。 @DeepakKanyan 使用 Navigator.pushReplacement() 而不是 Navigator.push() ,然后当前活动将从堆栈中删除 这个答案与问题无关【参考方案2】:

运行以下代码,按下主页按钮,然后重新打开应用程序以查看它是否正常工作。有4个AppLifecycleState

已恢复:应用程序可见并响应用户输入。

inactive:应用程序处于非活动状态,没有接收用户输入。

暂停:应用程序当前对用户不可见,不响应用户输入,并在后台运行。

分离:应用程序仍然托管在颤振引擎上,但与任何主机视图分离。

空安全码:

class MyPage extends StatefulWidget 
  @override
  _MyPageState createState() => _MyPageState();


class _MyPageState extends State<MyPage> with WidgetsBindingObserver 
  @override
  void initState() 
    super.initState();
    WidgetsBinding.instance!.addObserver(this);
  

  @override
  void dispose() 
    WidgetsBinding.instance!.removeObserver(this);
    super.dispose();
  

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) 
    super.didChangeAppLifecycleState(state);
    print('Current state = $state');
  

  @override
  Widget build(BuildContext context) => Scaffold();

【讨论】:

【参考方案3】:

要在应用程序进入前台或弹出路由时收到通知,您可以继承 LifecycleState 类并覆盖 onResume()onPause() 方法。 LifecycleState类:

/// Inherit this State to be notified of lifecycle events, including popping and pushing routes.
///
/// Use `pushNamed()` or `push()` method to track lifecycle events when navigating to another route.
abstract class LifecycleState <T extends StatefulWidget> extends State<T>
    with WidgetsBindingObserver 
  ResumeResult resumeResult = new ResumeResult();
  bool _isPaused = false;

  AppLifecycleState lastAppState = AppLifecycleState.resumed;

  void onResume() 

  void onPause() 

  /// Use instead of Navigator.push(), it fires onResume() after route popped
Future<T> push<T extends Object>(BuildContext context, Route<T> route, [String source]) 
    _isPaused = true;
    onPause();

    return Navigator.of(context).push(route).then((value) 
        _isPaused = false;

        resumeResult.data = value;
        resumeResult.source = source;

        onResume();
        return value;
    );


/// Use instead of Navigator.pushNamed(), it fires onResume() after route popped
Future<T> pushNamed<T extends Object>(BuildContext context, String routeName, Object arguments) 
    _isPaused = true;
    onPause();

    return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments).then((value) 
        _isPaused = false;

        resumeResult.data = value;
        resumeResult.source = routeName;

        onResume();
        return value;
    );


  @override
  void initState() 
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  

  @override
  void dispose() 
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) 
    if (state == AppLifecycleState.paused) 
      if (!_isPaused) 
        onPause();
      
     else if (state == AppLifecycleState.resumed &&
        lastAppState == AppLifecycleState.paused) 
      if (!_isPaused) 
        onResume();
      
    
    lastAppState = state;
  


class ResumeResult 
  dynamic data;
  String source;

还要确保使用push()pushNamed() 方法开始推送新路由。

【讨论】:

以上是关于如何使用 Flutter 处理应用程序生命周期(在 Android 和 iOS 上)?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter - 了解 Provider、Bloc 的生命周期以及何时处理流 [重复]

Flutter-如何在flutter的整个应用程序生命周期中将数据保存在内存中?

flutter实践 - flutter中的生命周期

Flutter State 的生命周期

Flutter实战之Flutter应用生命周期 AppLifecycleState浅析

Flutter实战之Flutter应用生命周期 AppLifecycleState浅析