dart 如何在Flutter App中处理onPause/onResume?

l2osamch  于 2023-09-28  发布在  Flutter
关注(0)|答案(3)|浏览(141)

我是Dart/Flutter的新手,想构建一个简单的应用程序,其中LinearProgressBar每秒更新一次。
在不深入实际代码的情况下,我使用了以下设置。

  • 一个函数,根据过去的时间计算进度。
  • LinearProgressBar显示进度。
  • 一个周期性的计时器,每秒重新计算进度并更新进度条。
  • 我每次调试打印'tick',重新计算就完成了。

一切都像预期的那样工作,只有一个例外。当我在Android设备的后台移动应用程序时,“滴答”不断被打印出来。
在原生Android上,当'onPause'事件被触发时,我会取消我的定期定时器。
Flutter中是否有类似的内容?我能找到的只有“initState”和“disposes”。但是,将应用程序移到后台时不会调用Dispose。
我不想让计时器一直在后台滴答作响。
在我的研究中,我发现了这个堆栈溢出问题onresume-and-onpause-for-widgets-on-flutter。答案建议使用TickerProviderStateMixin
我用下面的方式。

class _BarItemState extends State<BarItem> with SingleTickerProviderStateMixin {
    Ticker ticker;
    num progress = 1.0;

    @override
    void initState() {
       super.initState();
       ticker = createTicker((duration) => setState(() {
          debugPrint('tick');
          progress = duration.inSeconds / 30;
       }))
      ..start();
    }

    // other stuff omitted

}

它正在工作,但我仍然不满意。
原因是,现在每几毫秒调用一次代码回调,而不是每秒钟调用一次。这对我来说似乎是一种资源浪费(我不需要一个平滑的动画),...我是不是把事情搞复杂了
即使看起来我的用例不需要它,我仍然想知道:
如何自己处理onPause/onResume事件?

7lrncoxx

7lrncoxx1#

您可以覆盖WidgetBindingObserver接口的didChangeAppLifecycleState,以接收 * 应用生命周期 * 更改的通知。
this page中有示例代码

hfyxw5xn

hfyxw5xn2#

您可以从SystemChannels使用lifecycle通道。
范例:

SystemChannels.lifecycle.setMessageHandler((msg){
  debugPrint('SystemChannels> $msg');
});

输出量:

I/flutter ( 3672): SystemChannels> AppLifecycleState.paused
I/flutter ( 3672): SystemChannels> AppLifecycleState.resumed
s3fp2yjn

s3fp2yjn3#

从Flutter 3.13开始,我们可以采用新的方法AppLifecycleListener代替WidgetBindingObserver,它比WidgetBindingObserver有一些额外的功能
Dart Pad example
创建有状态类并声明App生命周期侦听器属性

late final AppLifecycleListener _listener;

initState中创建AppLifecycleListener类示例,并在其中传递所需的回调,如下图所示

@override
  void initState() {
    lifeCycleListener = AppLifecycleListener(
      onStateChange: _onLifeCycleChanged
    );
    super.initState();
  }

处理监听器

@override
  void dispose() {
    lifeCycleListener.dispose();
    super.dispose();
  }

基于生命周期实现logic _onLifeCycleChanged

void _onLifeCycleChanged(AppLifecycleState state) {
    switch(state){
      case AppLifecycleState.detached:
        // TODO: Handle this case.
      case AppLifecycleState.resumed:
        // TODO: Handle this case.
      case AppLifecycleState.inactive:
        // TODO: Handle this case.
      case AppLifecycleState.hidden:
        // TODO: Handle this case.
      case AppLifecycleState.paused:
        // TODO: Handle this case.
    }
  }

WidgetsBindingObserver中,当覆盖didChangeAppLifecycleState方法时,我们只能监听实际的状态变化,例如您的应用何时进入恢复状态。在AppLifecycleListener中,我们可以监听状态之间的转换,例如您的应用是否从非活动状态进入恢复状态,如下图所示。

lifeCycleListener = AppLifecycleListener(
      onStateChange: _onLifeCycleChanged,
      onDetach: _onDetach,
      onPause: _onPause
      ....
    );

   /// on Detach this will be called
  _onDetach() => print('on Detach');
  _onPause() => print('on Pause');
  ....

还有一个功能是onExitRequested回调,我们可以在关闭应用程序之前提醒用户,我想这将用于基于桌面的应用程序

AppLifecycleListener(
      onExitRequested: _onExit
    );

  Future<AppExitResponse> _onExit() async {
    final response = await showDialog<AppExitResponse>(
      context: context,
      barrierDismissible: false,
      builder: (context) => AlertDialog(
        title: const Text('Are you sure you want to close app?'),
        content: const Text('All unsaved date will be lost.'),
        actions: [
          TextButton(
            child: const Text('Cancel'),
            onPressed: () {
              Navigator.of(context).pop(AppExitResponse.cancel);
            },
          ),
          TextButton(
            child: const Text('Exist the App'),
            onPressed: () {
              Navigator.of(context).pop(AppExitResponse.exit);
            },
          ),
        ],
      ),
    );

    return response ?? AppExitResponse.exit;
  }

相关问题