当前位置:首页 > 科技  > 软件

了解并解决 Flutter 中的灰屏问题

来源: 责编: 时间:2024-06-14 08:51:14 71观看
导读生产中的 flutter 应用程序中的灰屏是一种通用占位符,当框架遇到问题无法渲染预期用户界面时就会显示。是的,所以基本上是出现问题时的后备指示器。有趣的是,这只出现在发布模式下。在任何其他模式下运行都会显示红色错

生产中的 flutter 应用程序中的灰屏是一种通用占位符,当框架遇到问题无法渲染预期用户界面时就会显示。是的,所以基本上是出现问题时的后备指示器。guv28资讯网——每日最新资讯28at.com

有趣的是,这只出现在发布模式下。在任何其他模式下运行都会显示红色错误屏幕,并说明导致错误的原因。(检查此处以了解各种类型的构建模式。)此类错误的常见原因是:guv28资讯网——每日最新资讯28at.com

  • 未处理的异常:这些是运行时发生的错误,未使用 try-catch 块捕获。
  • 渲染错误:这些是渲染布局时引起的问题,例如,在 Column 、 Row 或 Flex 小部件外部使用 Expanded 时引起的问题。

以下是可能导致灰屏的代码示例:guv28资讯网——每日最新资讯28at.com

class HomeView extends HookWidget {  const HomeView({super.key});  @override  Widget build(BuildContext context) {    const widget = null;    return Scaffold(      appBar: AppBar(        title: Text(          'Gallery',          style: Theme.of(context).textTheme.headlineLarge,        ),      ),      body: widget!,    );  }}

在这里,我们犯了一个明显的错误,在我们知道的 null 小部件上使用了 bang 运算符(!),这导致在非发布模式下出现红屏,在发布模式下出现灰屏。guv28资讯网——每日最新资讯28at.com

需要注意的是,我们不建议在不更新的情况下将部件明确设置为空值,空值错误是一个常见错误,而上述操作是重现该错误的简单方法。guv28资讯网——每日最新资讯28at.com

图片图片guv28资讯网——每日最新资讯28at.com

调试模式下的红色错误屏幕(左)和发布模式下的灰色屏幕(右)的图像调试模式下的红色错误屏幕(左)和发布模式下的灰色屏幕(右)的图像guv28资讯网——每日最新资讯28at.com

自定义错误屏幕

为了显示更用户友好的消息而不是灰屏,我们将策略性地在 main 函数中放置一行代码。该行充当预防措施,确保每当发生未处理的异常时都会显示自定义错误屏幕。guv28资讯网——每日最新资讯28at.com

void main() {  ErrorWidget.builder = (_) => const AppErrorWidget(); // This line does the magic!  runApp(MyApp());}

有条件的红屏(可选):

也许您希望在开发过程中看到默认的红色错误屏幕以进行调试。您可以通过将 ErrorWidget.builder 赋值包装在检查当前构建模式的 if 语句中来实现此目的:guv28资讯网——每日最新资讯28at.com

void main() {  if (kReleaseMode) ErrorWidget.builder = (_) => const AppErrorWidget();  runApp(MyApp());}

下一步涉及创建 AppErrorWidget 本身的内容。该小部件将确定发生未处理的异常时用户看到的内容。guv28资讯网——每日最新资讯28at.com

class AppErrorWidget extends StatelessWidget {  const AppErrorWidget({super.key});  @override  Widget build(BuildContext context) {    return const Material(      color: Colors.white,      child: Padding(        padding: EdgeInsets.all(24),        child: Column(          mainAxisAlignment: MainAxisAlignment.center,          mainAxisSize: MainAxisSize.min,          children: [            Icon(              Icons.warning,              size: 200,              color: Colors.amber,            ),            SizedBox(height: 48),            Text(              'So... something funny happened',              textAlign: TextAlign.center,              style: TextStyle(                fontSize: 24,                fontWeight: FontWeight.bold,              ),            ),            SizedBox(height: 16),            Text(              'This error is crazy large it covers your whole screen. But no worries'              ' though, we/'re working to fix it.',              textAlign: TextAlign.center,              style: TextStyle(                fontSize: 16,              ),            ),          ],        ),      ),    );  }}

AppErrorWidget 小部件的结果显示AppErrorWidget 小部件的结果显示guv28资讯网——每日最新资讯28at.com

虽然鼓励自定义应用程序的体验,但 ErrorWidget.builder 上的 Flutter 文档提醒我们,调用错误小部件时视图处于不稳定状态。构建(可能还有布局)期间的异常会使系统处于脆弱状态。为了最大限度地减少进一步的问题,返回的小部件应该做最少的工作。LeafRenderObjectWidget (如默认的 RenderErrorBox )非常适合处理意外约束。guv28资讯网——每日最新资讯28at.com

ErrorWidget.builder 的幕后花絮

现在我们知道,当渲染预期 UI 的过程中发生错误时, ErrorWidget.builder 就会被调用,但是这到底是如何实现的呢?guv28资讯网——每日最新资讯28at.com

如果我们深入研究 Flutter 的框架,我们会在构建或重建小部件时看到一个名为 _updateChild() 的方法。guv28资讯网——每日最新资讯28at.com

void _updateChild() {  try {    final Widget child = (widget as _RawView).builder(this, _effectivePipelineOwner);    _child = updateChild(_child, child, null);  } catch (e, stack) {    final FlutterErrorDetails details = FlutterErrorDetails(      exception: e,      stack: stack,      library: 'widgets library',      context: ErrorDescription('building $this'),      informationCollector: !kDebugMode ? null : () => <DiagnosticsNode>[        DiagnosticsDebugCreator(DebugCreator(this)),      ],    );    FlutterError.reportError(details);    final Widget error = ErrorWidget.builder(details);    _child = updateChild(null, error, slot);  }}

我们可以看到 ErrorWidget.builder 属性用于根据提供的 FlutterErrorDetails 检索自定义错误小部件;然后更新 _child 变量以显示自定义错误小部件而不是原始子小部件。guv28资讯网——每日最新资讯28at.com

提升开发者体验

定制向用户呈现错误的方式是改善用户体验的关键一步。虽然 ErrorWidget.builder 帮助我们在出现错误时管理用户体验,但它并没有为生产环境中的开发人员提供有价值的见解。本地调试不再是一种选择,那么我们如何及时了解用户设备上发生的错误呢?guv28资讯网——每日最新资讯28at.com

这就是我们利用 FlutterError.onError 回调的力量的地方。让我们看看这是如何完成的:guv28资讯网——每日最新资讯28at.com

void main() {  if (kReleaseMode) ErrorWidget.builder = (_) => const AppErrorWidget();  FlutterError.onError = (details) {    FlutterError.dumpErrorToConsole(details);    if (!kReleaseMode) return;    // 发送到您的 crashlytics 服务...  };  runApp(MyApp());}

我们添加了一行新代码,它将新的回调函数分配给 FlutterError.onError 属性。每当使用 FlutterError.reportError 报告错误时都会调用此回调。guv28资讯网——每日最新资讯28at.com

在回调内部, FlutterError.dumpErrorToConsole(details) 通过将错误详细信息转储到控制台来帮助我们了解幕后情况。这对于在部署或分阶段部署期间可能存在对用户设备的访问受限的调试目的非常有用。guv28资讯网——每日最新资讯28at.com

最后的注释行 ( // 发送到您的 crashlytics 服务... ) 强调了这种方法的真正威力。在这里,您可以集成您选择的错误报告服务(例如 Crashlytics)以发送详细的错误报告以供分析。guv28资讯网——每日最新资讯28at.com

注意:此行包含在 if 语句中,以确保它仅在调试或分析模式下执行 ( !kReleaseMode )。guv28资讯网——每日最新资讯28at.com

避免灰屏的最佳错误处理实践

我们已经了解了导致灰屏的原因以及出现灰屏时如何更好地处理它;我们还应该介绍的一件事是,作为开发人员可以采取哪些措施来避免出现灰屏。其中一些是:guv28资讯网——每日最新资讯28at.com

  • 拥抱 try-catch :将关键代码部分包装在 try-catch 块内。这允许您捕获潜在的异常并提供优雅的回退机制。
  • **少用 Bang 运算符 (!)**:bang 运算符 (!) 是 null 断言检查的快捷方式,但如果用于不确定是否为非 null 的值,可能会导致意外错误。更多地使用条件表达式 (??) 或 null 感知访问运算符 (?.)。
  • 彻底的应用程序测试:结合使用单元、小部件、集成和手动测试来帮助在问题出现在生产中之前识别和解决问题。
  • 尊重 Widget 约束:Flutter 中的每个 Widget 都有局限性和预期的使用模式;避免在其限制之外使用它们,例如在可滚动视图中使用 Spacer 。

结论:拥抱不可避免的事情

错误处理是任何编写良好的 Flutter 应用程序的重要组成部分。当您努力编写干净的代码并预测潜在问题时,异常情况必然会发生。通过实施 ErrorWidget.builder ,您可以确保即使发生意外情况,您的用户也会看到清晰且内容丰富的消息,而不是令人困惑的灰屏,并且通过 FlutterError.onError 您可以确保您记录这些意外错误,并且可以更轻松地调试和修复这些错误。guv28资讯网——每日最新资讯28at.com

请记住,即使面对不可预见的障碍,一点准备对于保持积极的用户和开发人员体验也大有帮助。guv28资讯网——每日最新资讯28at.com

原文:https://medium.com/@LordChris/understanding-and-addressing-the-grey-screen-in-flutter-5e72c31f408fguv28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-93688-0.html了解并解决 Flutter 中的灰屏问题

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 生成式人工智能是 DevSecOps 的福音还是噩梦?

下一篇: 为什么很多人用Java好几年,还是不太理解泛型?

标签:
  • 热门焦点
  • 5月安卓手机好评榜:魅族20 Pro夺冠

    5月安卓手机好评榜:魅族20 Pro夺冠

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年5月1日至5月31日,仅限国内市场。第一名:魅族20 Pro好评率:97.50%不得不感慨魅族老品牌还
  • 十个可以手动编写的 JavaScript 数组 API

    十个可以手动编写的 JavaScript 数组 API

    JavaScript 中有很多API,使用得当,会很方便,省力不少。 你知道它的原理吗? 今天这篇文章,我们将对它们进行一次小总结。现在开始吧。1.forEach()forEach()用于遍历数组接收一参
  • 微信语音大揭秘:为什么禁止转发?

    微信语音大揭秘:为什么禁止转发?

    大家好,我是你们的小米。今天,我要和大家聊一个有趣的话题:为什么微信语音不可以转发?这是一个我们经常在日常使用中遇到的问题,也是一个让很多人好奇的问题。让我们一起来揭开这
  • 一篇文章带你了解 CSS 属性选择器

    一篇文章带你了解 CSS 属性选择器

    属性选择器对带有指定属性的 HTML 元素设置样式。可以为拥有指定属性的 HTML 元素设置样式,而不仅限于 class 和 id 属性。一、了解属性选择器CSS属性选择器提供了一种简单而
  • 雅柏威士忌多款单品价格大跌,泥煤顶流也不香了?

    雅柏威士忌多款单品价格大跌,泥煤顶流也不香了?

    来源 | 烈酒商业观察编 | 肖海林今年以来,威士忌市场开始出现了降温迹象,越来越多不断暴涨的网红威士忌也开始悄然回归市场理性。近日,LVMH集团旗下苏格兰威士忌品牌雅柏(Ardbeg
  • ESG的面子与里子

    ESG的面子与里子

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之三伏大幕拉起,各地高温预警不绝,但处于厄尔尼诺大&ldquo;烤&rdquo;之下的除了众生,还有各大企业发布的ESG报告。ESG是&ldquo;环境保
  • AMD的AI芯片转单给三星可能性不大 与台积电已合作至2nm制程

    AMD的AI芯片转单给三星可能性不大 与台积电已合作至2nm制程

    据 DIGITIMES 消息,英伟达 AI GPU 出货逐季飙升,接下来 AMD MI 300 系列将在第 4 季底量产。而半导体业内人士表示,近日传出 AMD 的 AI 芯片将转单给
  • iQOO Neo8系列今日官宣:首发天玑9200+ 全球安卓最强芯!

    iQOO Neo8系列今日官宣:首发天玑9200+ 全球安卓最强芯!

    在昨日举行的的联发科新一代旗舰芯片天玑9200+的发布会上,iQOO官方也正式宣布,全新的iQOO Neo8系列新品将全球首发搭载这款当前性能最强大的移动平台
  • 苹果MacBook Pro 2021测试:仍不支持平滑滚动

    苹果MacBook Pro 2021测试:仍不支持平滑滚动

    据10月30日9to5 Mac 消息报道,苹果新的 14 英寸和 16 英寸 MacBook Pro 2021 上市后获得了不错的评价,亮点包括行业领先的性能,令人印象深刻的电池续航,精美丰
Top