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

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

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

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

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

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

以下是可能导致灰屏的代码示例:YNv28资讯网——每日最新资讯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 运算符(!),这导致在非发布模式下出现红屏,在发布模式下出现灰屏。YNv28资讯网——每日最新资讯28at.com

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

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

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

自定义错误屏幕

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

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

有条件的红屏(可选):

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

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

下一步涉及创建 AppErrorWidget 本身的内容。该小部件将确定发生未处理的异常时用户看到的内容。YNv28资讯网——每日最新资讯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 小部件的结果显示YNv28资讯网——每日最新资讯28at.com

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

ErrorWidget.builder 的幕后花絮

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

如果我们深入研究 Flutter 的框架,我们会在构建或重建小部件时看到一个名为 _updateChild() 的方法。YNv28资讯网——每日最新资讯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 变量以显示自定义错误小部件而不是原始子小部件。YNv28资讯网——每日最新资讯28at.com

提升开发者体验

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

这就是我们利用 FlutterError.onError 回调的力量的地方。让我们看看这是如何完成的:YNv28资讯网——每日最新资讯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 报告错误时都会调用此回调。YNv28资讯网——每日最新资讯28at.com

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

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

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

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

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

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

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

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

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

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

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

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

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

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

标签:
  • 热门焦点
  • 7月安卓手机性能榜:红魔8S Pro再夺榜首

    7月份的手机市场风平浪静,除了红魔和努比亚带来了两款搭载骁龙8Gen2领先版处理器的新机之外,别的也想不到有什么新品了,这也正常,通常6月7月都是手机厂商修整的时间,进入8月份之
  • 6月iOS设备性能榜:M2稳居榜首 A系列只能等一手3nm来救

    没有新品发布,自然iOS设备性能榜的上榜设备就没有什么更替,仅仅只有跑分变化而产生的排名变动,毕竟苹果新品的发布节奏就是这样的,一年下来也就几个移动端新品,不会像安卓厂商,一
  • 容量越大越不坏?24万块硬盘故障率报告公布 这些产品零故障

    8月5日消息,云存储服务商Backblaze发布了最新的硬盘故障率报告,年故障率有所上升。Backblaze发布的硬盘季度统计数据,其中包括故障率等重要方面。这些结
  • JavaScript 混淆及反混淆代码工具

    介绍在我们开始学习反混淆之前,我们首先要了解一下代码混淆。如果不了解代码是如何混淆的,我们可能无法成功对代码进行反混淆,尤其是使用自定义混淆器对其进行混淆时。什么是混
  • Rust中的高吞吐量流处理

    作者 | Noz编译 | 王瑞平本篇文章主要介绍了Rust中流处理的概念、方法和优化。作者不仅介绍了流处理的基本概念以及Rust中常用的流处理库,还使用这些库实现了一个流处理程序
  • 2纳米决战2025

    集微网报道 从三强争霸到四雄逐鹿,2nm的厮杀声已然隐约传来。无论是老牌劲旅台积电、三星,还是誓言重回先进制程领先地位的英特尔,甚至初成立不久的新
  • 2299元起!iQOO Pad开启预售:性能最强天玑平板

    5月23日,iQOO如期举行了新品发布会,除了首发安卓最强旗舰处理器的iQOO Neo8系列新机外,还在发布会上推出了旗下首款平板电脑——iQOO Pad,其搭载了天玑
  • 引领旗舰级影像能力向中端机普及 OPPO K11 系列发布 1799 元起

    7月25日,OPPO正式发布K系列新品—— OPPO K11 。此次 K11 在中端手机市场长期被忽视的影像板块发力,突破性地搭载索尼 IMX890 旗舰大底主摄,支持 OIS
  • DRAM存储器10月价格下跌,NAND闪存本月价格与上月持平

    10月30日,据韩国媒体消息,自今年年初以来一直在上涨的 DRAM 存储器的交易价格仅在本月就下跌了近 10%,此次是全年首次降价,而NAND 闪存本月价格与上月持平。市
Top