【问题标题】:How to refactor this code to avoid passing BuildContext between async scopes?如何重构此代码以避免在异步范围之间传递 BuildContext?
【发布时间】:2022-08-13 03:09:10
【问题描述】:

我有一个 PermissionsManager 类,对于这个特定的方法,我得到了一个“不要在异步间隙中使用 BuildContext”:

class PermissionsManager {
  static Future<void> requestLocationPermission(BuildContext context) async {
    final status = await Permission.location.request();

    if (!status.isGranted) {
      await showOpenSettingsDialog(context,
          title: \"Grant Location Access\",
          message:
              \"TODO\");
    }
  }
}

我曾考虑将其拆分为多个函数,但调用者需要检查状态,并根据状态调用另一个显示此对话框的方法。

有没有办法以相同的方法执行此操作并处理此构建上下文问题?

    标签: flutter


    【解决方案1】:

    好问题!假设您处于“有状态小部件”中,请在使用 BuildContext 之前添加 if (mounted) 检查以跨越异步间隙。

    例如:

        onPressed: () async {
          final status = await Future.delayed(const Duration(seconds: 1));
          if (mounted) { // <-- add this check
            if (!status.isGranted) {
              showOpenSettingsDialog(context);
            }
          }
        }
    

    我们不想在异步间隙中使用BuildContext 的原因是,在等待期间小部件可能已变为unmounted。如果我们检查if (mounted),我们不会有这个问题。基本上,如果小部件在等待期间以某种方式被破坏,我们只是不再显示对话框。

    如果这是一个无状态小部件,您可以将其转换为有状态小部件。

    你也可以阅读我对这个主题的详细解释here

    【讨论】:

    • 我懂了。由于这不是一个小部件,而只是一个带有一些静态方法的简单类,我怎么知道它是否已挂载?我想这是我的困惑,因为它存在于 UI 小部件之外,并且存在于它自己的东西中。谢谢!
    【解决方案2】:

    在执行 requestLocationPermission 函数之前存储 NavigatorState,然后使用它来处理导航:

    onPressed: () async {
      final navigator = Navigator.of(context); // store the Navigator
      await requestLocationPermission(navigator); // use the Navigator, not the BuildContext
    },
    
    class PermissionsManager {
      static Future<void> requestLocationPermission(NavigatorState navigator) async {
        final status = await Permission.location.request();
    
        if (!status.isGranted) {
          await showOpenSettingsDialog(
              context,
              title: "Grant Location Access",
              message: "TODO",
          );
        }
        navigator.pop(); // Do whatever with your navigator;
      }
    }
    

    这个答案基本上是一个简写:https://stackoverflow.com/a/69512692

    我强烈建议您查看它以获得更详细的解释。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-26
      • 2019-03-27
      • 2013-09-25
      相关资源
      最近更新 更多