ios - 有了这个 `didChangeAppLifecycleState` 实现,为什么我在解锁 iOS 设备后会短暂地看到之前的屏幕?

标签 ios flutter dart

我的 Flutter 应用程序中有一个 StatefulWidgetStatefulWidget 具有以下属性集:

final pausedTimeAllowed = 0;

这是我在该小部件的 State 类中实现的 didChangeAppLifecycleState:

@override void didChangeAppLifecycleState(AppLifecycleState state) {
  super.didChangeAppLifecycleState(state);
  if (!(ModalRoute.of(context)!.isCurrent)) {
    return;
  }
  switch (state) {
    case AppLifecycleState.resumed:
      debugPrint("didChangeAppLifecycleState: resumed");
      if ((globals.pausedSince is DateTime) && (DateTime.now().difference(globals.pausedSince).inSeconds > widget.pausedTimeAllowed)) {
        globals.pausedSince = null;
        Navigator.of(context).pushReplacementNamed('/');
      } else {
        setState(() {
          showInactiveOverlay = false;
        });
      }
      break;
    case AppLifecycleState.inactive:
      debugPrint("didChangeAppLifecycleState: inactive");
      setState(() {
        showInactiveOverlay = true;
      });
      break;
    case AppLifecycleState.paused:
      debugPrint("didChangeAppLifecycleState: paused");
      if (widget.pausedTimeAllowed > 0) {
        debugPrint("didChangeAppLifecycleState: paused | setting `pausedSince`…");
        globals.pausedSince = DateTime.now();
      } else {
        debugPrint("didChangeAppLifecycleState: paused | navigating to /…");
        Navigator.of(context).pushReplacementNamed('/');
      }
      break;
  }
}

当这条路线在用户屏幕上可见并且他们让手机进入休眠状态时,我注意到应用的 inactivepaused 状态被触发但是在解锁设备时在应用程序上,我短暂地(大约 0.5-1 秒)看到屏幕闪烁,然后被导航到/。

为什么它还没有在/上?

此外,尽管触发了应用的 inactive 状态,但值得注意的是,我没有看到非事件叠加层 (showInactiveOverlay)是背景化的(例如,当它进入切换器时)。

我是否期望 didChangeAppLifecycleState 回调来处理这些错误线程?

最佳答案

TL;DR:我假设 sleep 模式会触发inactive -> paused 状态,而解锁只会触发paused 状态。

基于 Flutter's official documentation关于生命周期事件,我假设当用户将手机置于 sleep 模式时,它首先进入 inactive 状态,然后进入 paused

另一方面,当用户锁定屏幕时,这是一个意外的 Action ,它会导致 paused 状态立即被触发(没有 inactive 状态) .

因此,如果我理解正确的话,当您的用户在解锁后恢复时,到主屏幕“/”的导航仍然需要反射(reflect)。这就是他们在导航前看到屏幕闪烁的原因。

这是 official description对于每个生命周期事件:

已恢复

该应用程序是可见的并响应用户输入。

无效

应用程序处于非事件状态,不接收用户输入。

在 iOS 上,此状态对应于在前台非事件状态下运行的应用程序或 Flutter 主机 View 。当通话、响应 TouchID 请求、进入应用程序切换器或控制中心时,或者当托管 Flutter 应用程序的 UIViewController 正在转换时,应用程序会转换到此状态。

在 Android 上,这对应于在前台非事件状态下运行的应用程序或 Flutter 主机 View 。当另一个 Activity 获得焦点时,应用会转换到此状态,例如分屏应用、电话、画中画应用、系统对话框或另一个窗口。

处于此状态的应用应假定它们可能随时暂停。

暂停

该应用当前对用户不可见,不响应用户输入,并在后台运行。

当应用程序处于此状态时,引擎将不会调用 PlatformDispatcher.onBeginFrame 和 PlatformDispatcher.onDrawFrame 回调。

独立

该应用程序仍托管在 Flutter 引擎上,但与任何主机 View 分离。

当应用程序处于此状态时,引擎在没有 View 的情况下运行。它可以在引擎首次初始化时正在附加 View ,也可以在 View 由于导航器弹出而被销毁之后。

关于ios - 有了这个 `didChangeAppLifecycleState` 实现,为什么我在解锁 iOS 设备后会短暂地看到之前的屏幕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73622009/

相关文章:

asynchronous - net不在时如何处理socket异常?

flutter - 如何自动加载对话框并消除抖动?

flutter - 在 Flutter 中将图像 Assets 转换为 base64

ios - 拍照,在相机中选择完整模式或方形模式

ios - Knock to unlock 如何在后台可靠地检测 sleep 电话上的敲门声?

flutter - 如何向 `showSearch` 提供 BLoC(带有 flutter_bloc)

flutter - 如何使用 flutter cloud_firestore 插件从 DocumentID 获取 documetReference

iphone - phonegap iphone外部网址

ios - 使用 XCUI 进行 UI 测试

android - 在 WKWebView/UIWebView 中启用 WebRTC 支持