Flutter 中的Error的捕获及处理

简介: Flutter 框架可以捕获运行期间的错误,包括构建期间、布局期间和绘制期间。所有 Flutter 的错误均会被回调方法 FlutterError.onError 捕获。默认情况下,会调用 FlutterError.dumpErrorToConsole 方法,正如方法名表示的那样,将错误转储到当前的设备日志中。当从 IDE 运行应用时,检查器重写了该方法,错误也被发送到 IDE 的控制台,可以在控制台中检查出错的对象。

捕获Flutter错误



重写FlutterError的onError即可,如下:


import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() {
  FlutterError.onError = (FlutterErrorDetails details) {
    FlutterError.dumpErrorToConsole(details);
    if (kReleaseMode)
      ... //处理线上错误,如统计上传
  };
  runApp(MyApp());
}
复制代码


上面我们重写了FlutterError.onError,这样就可以捕获到错误,第一行代码就是将error展示到控制台,这样我开发时就会在控制台很方便的看到错误。下面代码就是在线上环境下,对错误进一步处理,比如统计上传。


自定义ErrorWidget


上面我们知道,构建时发生错误会默认展示一个错误页面,但是这个页面很不友好,我们可以自定义一个错误页面。定义一个自定义的 error widget,以当 builder 构建 widget 失败时显示,请使用 MaterialApp.builder。


class MyApp extends StatelessWidget {
...
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      ...
      builder: (BuildContext context, Widget widget) {
        Widget error = Text('...rendering error...');
        if (widget is Scaffold || widget is Navigator)
          error = Scaffold(body: Center(child: error));
        ErrorWidget.builder = (FlutterErrorDetails errorDetails) => error;
        return widget;
      },
    );
  }
}
复制代码


在App下的builder中,自定义一个error页面,然后赋值给ErrorWidget.builder即可。这样再出现错误的时候就可以展示一个友好的页面。


无法捕获的错误


假设一个 onPressed 回调调用了异步方法,例如 MethodChannel.invokeMethod (或者其他 plugin 的方法):


OutlinedButton(
  child: Text('Click me!'),
  onPressed: () async {
    final channel = const MethodChannel('crashy-custom-channel');
    await channel.invokeMethod('blah');
  },
),
复制代码


如果 invokeMethod 抛出了错误,它不会传递至 FlutterError.onError,而是直接进入 runApp 的 Zone。

如果你想捕获这样的错误,请使用 runZonedGuarded。代码如下:


import 'dart:async';
void main() {
  runZonedGuarded(() {
    runApp(MyApp());
  }, (Object error, StackTrace stack) {
    ... //处理错误
  });
}
复制代码


请注意,如果你的应用在 runApp 中调用了 WidgetsFlutterBinding.ensureInitialized() 方法来进行一些初始化操作(例如 Firebase.initializeApp()),则必须在 runZonedGuarded 中调用 WidgetsFlutterBinding.ensureInitialized()


runZonedGuarded(() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}
复制代码


如果 WidgetsFlutterBinding.ensureInitialized() 在外部调用,错误将不会被捕获到。


完整处理流程


如果要处理上面全部问题,则先通过runZonedGuarded处理异步错误,再通过FlutterError.onError处理,这些错误都通过一个我们自定义的MyErrorsHandler类来集中处理即可,比如统计上传等。然后在app中还需要定义一个友好的错误页面。


目录
相关文章
|
移动开发 Dart 监控
技术实践第二期|Flutter异常捕获
应用性能稳定是良好用户体验中非常关键的一环,为了更好保障应用性能稳定,异常捕获在保证线上产品稳定中扮演着至关重要的角色。我们团队在推出了U-APM移动应用性能监控的产品后,帮助开发者定位并解决掉很多线上的疑难杂症。随着使用人数的增多,关注度的提高,在拜访客户和开发者的留言中,很多开发者都提出希望该产品可以支持flutter框架的异常捕获。本身我并没有做过flutter开发,所以主要是通过在现有产品能力基础上做插件实现异常的上报,这篇文章就记录我学习flutter错误处理的过程和遇到的问题。
技术实践第二期|Flutter异常捕获
|
18天前
|
缓存 监控 前端开发
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略
【4月更文挑战第30天】本文探讨了Flutter应用启动优化策略,包括理解启动过程、资源加载优化、减少初始化工作、界面布局简化、异步初始化、预加载关键数据、性能监控分析以及案例和未来优化方向。通过这些方法,可以缩短启动时间,提升用户体验。使用Flutter DevTools等工具可助于识别和解决性能瓶颈,实现持续优化。
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略
|
16天前
|
前端开发 C++ 容器
Flutter-完整开发实战详解(一、Dart-语言和-Flutter-基础)(1)
Flutter-完整开发实战详解(一、Dart-语言和-Flutter-基础)(1)
|
18天前
|
开发框架 Dart 前端开发
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
【4月更文挑战第30天】对比 Flutter(Dart,强类型,Google支持,快速热重载,高性能渲染)与 React Native(JavaScript,庞大生态,热重载,依赖原生渲染),文章讨论了开发语言、生态系统、性能、开发体验、学习曲线、社区支持及项目选择因素。两者各有优势,选择取决于项目需求、团队技能和长期维护考虑。参考文献包括官方文档和性能比较文章。
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
|
6天前
|
Dart 安全
简化代码、提高效率:Dart和Flutter开发小技巧
在日常开发中,我们常常会使用一些常用的技巧或语法糖,以简化代码、提高开发效率。本文将分享一些在Dart和Flutter中常用的小贴士,帮助你更轻松地编写优雅高效的代码。
简化代码、提高效率:Dart和Flutter开发小技巧
|
17天前
|
Android开发
Flutter完整开发实战详解(六、 深入Widget原理),2024百度Android岗面试真题收录解析
Flutter完整开发实战详解(六、 深入Widget原理),2024百度Android岗面试真题收录解析
|
17天前
|
XML Dart Java
Flutter插件开发之APK自动安装,字节跳动Android岗面试题
Flutter插件开发之APK自动安装,字节跳动Android岗面试题
|
17天前
|
Java Android开发 设计模式
flutter音视频开发,Android开发需要学什么
flutter音视频开发,Android开发需要学什么
|
18天前
|
Dart 前端开发 测试技术
【Flutter前端技术开发专栏】Flutter开发中的代码质量与重构实践
【4月更文挑战第30天】随着Flutter在跨平台开发的普及,保证代码质量成为开发者关注的重点。优质代码能确保应用性能与稳定性,提高开发效率。关键策略包括遵循最佳实践,编写可读性强的代码,实施代码审查和自动化测试。重构实践在项目扩展时尤为重要,适时重构能优化结构,降低维护成本。开发者应重视代码质量和重构,以促进项目成功。
【Flutter前端技术开发专栏】Flutter开发中的代码质量与重构实践
|
18天前
|
存储 缓存 监控
【Flutter前端技术开发专栏】Flutter中的列表滚动性能优化
【4月更文挑战第30天】本文探讨了Flutter中优化列表滚动性能的策略。建议使用`ListView.builder`以节省内存,避免一次性渲染所有列表项。为防止列表项重建,可使用`UniqueKey`或`ObjectKey`。缓存已渲染项、减少不必要的重绘和异步加载大数据集也是关键。此外,选择轻量级组件,如`StatelessWidget`,并利用Flutter DevTools监控性能以识别和解决瓶颈。持续测试和调整以提升用户体验。
【Flutter前端技术开发专栏】Flutter中的列表滚动性能优化