【问题标题】:How to handle app lifecycle with Flutter (on Android and iOS)?如何使用 Flutter 处理应用程序生命周期(在 Android 和 iOS 上)?
【发布时间】:2019-11-20 06:53:07
【问题描述】:

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

喜欢:

onCreate()
onResume()
onDestroy()

或者:

viewDidload()
viewWillAppear()

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

【问题讨论】:

    标签: android ios dart 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 可以知道应用程序可以处于的状态,例如:

    1. 无效
    2. 暂停
    3. 已恢复
    4. 暂停

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

    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() 方法开始推送新路由。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-22
        • 2020-05-14
        • 2012-06-01
        • 1970-01-01
        • 2011-06-02
        相关资源
        最近更新 更多