前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >别在异步间隙中使用 BuildContext:为什么且如何正确处理 Flutter Context

别在异步间隙中使用 BuildContext:为什么且如何正确处理 Flutter Context

作者头像
Jimmy_is_jimmy
发布2024-06-26 08:52:21
1540
发布2024-06-26 08:52:21
举报
文章被收录于专栏:call_me_Rcall_me_R

原文链接:Do Not User BuildContext in Async Gaps: Why and How to Handle Flutter Context Corretly - 原文作者 Ashish

本文采用意译的方式

在本文中,我们将探讨一个在 Flutter 开发中经常被忽略的问题:在异步间隙中使用 BuildContext。我们将调查 Flutter 中这一关键部分的原因和方法,强调合适 context 处理的必要性,以避免潜在的错误和内存泄露。理解基础和最佳实践将帮助我们掌握 Flutter 异步编程的难点,确保我们的应用顺畅且快速运行。

banner.webp
banner.webp

这意味着什么?

别在异步间隙中使用 BuildContext 是一个重要的提示,提醒 Flutter 开发人员在执行异步操作时不要使用 BuildContext。在 Flutter 中,BuildContext 是一个重要的参数,用来获取在挂件树中一个挂件位置信息,然后执行一个任务,比如导航到其他屏幕,展示对话框,获取主题数据等等。

然而,当开发者跨越异步边界传递 BuildContext 时,比如在 Future MethodsStreamBuilder 或者脱离,它可能会导致问题。此告警反对这么做,因为这可能导致我们应用程序出现意外和错误的行为。

当在异步间隙中使用 BuildContext,它可能指向一个不存在的挂件,然后导致下面的问题:

  1. 过时数据:如果在异步操作正在进行时重建或者处置小部件,BuildContext 引用可能会指向过时或者不存在的小挂件。这可能导致在应用中展示错误或者展示过时的数据。
  2. 内存溢出:持有应用被释放的 BuildContext 的引用可能会导致内存泄漏,因为框架不能对其进行垃圾回收。
  3. 应用崩溃:在某些情况下,如果在操作完成前释放了引用的挂件,在异步间隙中使用 BuildContext 可能导致应用崩溃。

本质上,这告警就是要开发者认真考虑在异步操作中如何处理 BuildContext,强调明白挂件生命周期管理的重要性,避免可能影响我们 Flutter 引用程序可靠性和性能的常见陷阱。

我们应该怎么做?

方法1:使用 GlobalKeyKeyed Subtrees

为了解决不在异步间隙中使用 BuildContext 的问题,我们可以使用 GlobalKey 和键控子树 keyed subtrees。这个方法保证在异步操作中关联正确的 BuildContext,即使该挂件被处置并重建。

我们可以参考下面的例子,实现这个解决方案:

步骤1:创建一个 GlobalKey

在我们的 Widget State 中创建一个 GlobalKey 开始,然后附加在我们异步操作的父挂件上。这样就确保从这个 GlobalKey 获取的 BuildContext 是有效的。

代码语言:javascript
复制
final GlobalKey<_MyWidgetState> myWidgetKey = GlobalKey();

步骤2:取回 BuildContext

在我们的异步操作中,我们可以通过 GlobalKey 取回 BuildContext

代码语言:javascript
复制
Future<void> fetchData() async {
  /// 在挂件树中获取当前挂件的上下文 context
  final context = myWidgetKey.currentContext;
  
  var result = await navigator.of(context).pushNamed("/user_selection_page");
  
  if(context != null && context.mounted) {
    /// 在异步间隙后的声明不会告警
    Scaffold.of(context).showSnackBar(SnackBar(
      content: Text(result.name),
    ));
  }
}

通过这个方法,我们确保 BuildContext 在异步操作的过程中依旧是有效的,防止了与陈旧和无效上下文相关的问题。

好处:

  • 可靠的上下文 context:使用 GlobalKey 保证关联的 BuildContext 总是最新和准确的。
  • 可预测的行为:挂件子树依旧正确的和它各自的 BuildContext 关联,即使在异步操作的过程中。
  • 不易出错:这个方法减少了由于过时的 BuildContext 引用而导致错误和崩溃的可能。

然而,我们可以通过另一种方法处理同样的事情...

方法2:在 Future 中使用 then 方法

then 方法是处理需要使用有效 BuildContext 的异步操作的直接方法。它要确保我们的代码仅在异步操作成功后执行,因此其能获取正确的 BuildContext。下面例子展示我们如何应用该解决方法:

代码语言:javascript
复制
Future<void> fetchData() async {
  await navigator.of(context).pushNamed('/user_selection_page')
  .then((result) {
    /// 在异步间隙后的声明不会告警
    Scaffold.of(context).showSnackBar(SnackBar(
      content: Text(result.name),
    ));
  });
}

好处

  • 一致上下文:使用 then 方法确保代码在与异步操作相同的执行上下文中执行,从而提供对 BuildContext 的正确访问。
  • 清晰的工作流:代码保持有序且直观,逻辑遵循顺序的模式,使其更容易理解和维护。

题外话,如果你想在异步间隙中使用 BuildContext,但是这些告警让你很烦,那么,我们可以在文件 analysis_options.yaml 文件中添加 use_build_context_synchronously 规则:

代码语言:javascript
复制
linter:
  rules:
    - use_build_context_synchronously

总结

Flutter 开发中,拥有一个清晰且健壮的方法来处理异步操作很重要,以免因使用不正确的 BuildContext 而导致的问题。告警 "Do not user BuildContext in async gaps" 有助于提醒人们注意危险。

请记住,吸取最佳实践,比如上面提到的,能够引导我们编写更加健壮和有序的代码,最终带来更好的用户体验。因此,吸取经验,然后构建更高效和用户友好的 Flutter 应用程序。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 这意味着什么?
  • 我们应该怎么做?
    • 方法1:使用 GlobalKey 和 Keyed Subtrees
      • 方法2:在 Future 中使用 then 方法
      • 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档