Flutter中的异常处理有哪些?

Flutter 的异常处理机制包括 同步异常异步异常 ,涉及多个层面,如 Dart 语言级别的异常捕获Flutter 框架的错误处理机制自定义异常处理 以及 错误上报


1. Dart 语言级别的异常处理

Dart 主要使用 try-catch 进行异常捕获,并区分 同步异常异步异常 的处理方式。

1.1. 同步异常

同步代码中的异常可以通过 try-catch 捕获:

php 复制代码
dart
复制编辑
void main() {
  try {
    int result = 10 ~/ 0; // 除以 0,会触发异常
  } catch (e, stackTrace) {
    print("捕获异常: $e");
    print("堆栈信息: $stackTrace");
  }
}
  • e 捕获异常对象
  • stackTrace 获取异常发生的堆栈信息,方便调试

常见异常类型:

  • FormatException:数据格式错误
  • RangeError:数组越界
  • TypeError:类型转换错误
  • StateError:非法状态操作
  • ArgumentError:参数错误

1.2. 异步异常

Flutter 使用 异步编程(Future 和 Stream) ,因此要特别注意 FutureStream 的异常处理。

1.2.1. Future 异常处理

异步 Future 任务的异常需要使用 .catchError()try-catch 捕获:

csharp 复制代码
dart
复制编辑
Future<void> asyncTask() async {
  try {
    await Future.delayed(Duration(seconds: 1));
    throw Exception("异步任务异常");
  } catch (e) {
    print("捕获 Future 异常: $e");
  }
}

void main() {
  asyncTask();
}

另一种方式是 .catchError()

javascript 复制代码
dart
复制编辑
Future<void> asyncTask() {
  return Future.delayed(Duration(seconds: 1))
      .then((_) => throw Exception("异步任务异常"))
      .catchError((e) {
        print("Future 捕获异常: $e");
      });
}

1.2.2. Stream 异常处理

Stream 中的异常不会自动抛出,需要使用 handleError()try-catch 捕获:

dart 复制代码
dart
复制编辑
void main() {
  Stream<int> stream = Stream.periodic(Duration(seconds: 1), (count) {
    if (count == 2) throw Exception("Stream 发生错误");
    return count;
  }).take(5);

  stream.listen(
    (data) => print("收到数据: $data"),
    onError: (error) => print("捕获 Stream 异常: $error"),
  );
}

2. Flutter 框架级别的异常处理

Flutter 提供了一套全局异常处理机制,包括:

  • FlutterError.onError
  • PlatformDispatcher.instance.onError
  • runZonedGuarded

2.1. 处理 Flutter 框架错误 (FlutterError.onError)

Flutter 框架内部的异常(例如 setState() 期间的异常)会由 FlutterError.onError 处理:

scss 复制代码
dart
复制编辑
void main() {
  FlutterError.onError = (FlutterErrorDetails details) {
    print("Flutter 框架错误: ${details.exception}");
    print("错误详情: ${details.stack}");
  };

  runApp(MyApp());
}

应用场景

  • 捕获 UI 相关异常,如 build() 方法中的错误
  • 处理 Flutter 框架错误

2.2. 捕获 Native 层异常 (PlatformDispatcher.instance.onError)

PlatformDispatcher.instance.onError 可用于捕获 Flutter Engine 层的异常:

arduino 复制代码
dart
复制编辑
void main() {
  PlatformDispatcher.instance.onError = (error, stack) {
    print("捕获 Native 层异常: $error");
    return true; // 阻止异常冒泡
  };

  runApp(MyApp());
}

适用场景

  • 处理 Dart 代码未捕获的异常
  • 监听 Native 层的异常信息

2.3. 捕获 runZonedGuarded 异常

Dart 允许在 runZonedGuarded 中执行代码,确保 FutureStream 中的异常不会导致程序崩溃:

scss 复制代码
dart
复制编辑
void main() {
  runZonedGuarded(() {
    runApp(MyApp());
  }, (error, stackTrace) {
    print("runZonedGuarded 捕获到异常: $error");
  });
}

适用场景

  • 全局捕获 Future 异常
  • 防止异常导致 App 崩溃
  • 统一上报异常

3. 统一异常上报

在生产环境中,异常通常需要上报到日志系统(如 Sentry、Firebase Crashlytics)。

3.1. 结合 FlutterError.onError 进行上报

scss 复制代码
dart
复制编辑
void main() {
  FlutterError.onError = (FlutterErrorDetails details) {
    // 发送错误信息到服务器
    reportError(details.exception, details.stack);
  };

  runApp(MyApp());
}

void reportError(Object error, StackTrace? stack) {
  // 发送到 Sentry 或 Firebase
  print("上报错误: $error");
}

4. Widget 层面的异常捕获

有时,我们希望在 UI 层面防止崩溃,比如 build() 发生异常时显示默认 UI。

4.1. 使用 ErrorWidget

Flutter 允许替换 ErrorWidget,在 Widget 构建失败时显示自定义错误页面:

scss 复制代码
dart
复制编辑
void main() {
  ErrorWidget.builder = (FlutterErrorDetails details) {
    return Center(child: Text("发生错误: ${details.exceptionAsString()}"));
  };

  runApp(MyApp());
}

5. 总结

机制 作用 适用场景
try-catch 捕获同步异常 同步代码异常
catchError() 处理 Future 异常 异步异常
handleError() 处理 Stream 异常 Stream 发生错误
FlutterError.onError 捕获 Flutter 框架错误 Widget build() 失败
PlatformDispatcher.instance.onError 监听 Engine 级错误 Flutter Engine 发生崩溃
runZonedGuarded 保护全局异步代码 防止 Future 未捕获异常导致崩溃
ErrorWidget.builder 自定义 UI 错误页面 Widget 级别错误

6. 最佳实践

  1. 对所有 Future 代码使用 catchError()
  2. 对所有 Stream 监听使用 handleError()
  3. 使用 FlutterError.onError 统一收集 UI 相关异常
  4. 使用 runZonedGuarded 防止未捕获的异步异常
  5. 上报错误到日志服务(Sentry、Firebase Crashlytics)
  6. 自定义 ErrorWidget.builder 让 UI 崩溃可视化
  7. PlatformDispatcher.instance.onError 监听 Native 层错误

Flutter 的异常处理涉及多个层面,从 Dart 语言层、Flutter 框架层到 UI 组件层,掌握这些机制能有效提升 App 的稳定性,减少崩溃情况。

相关推荐
「、皓子~3 小时前
海狸IM 2.0 正式发布:六端齐发,开源 IM 迈入新阶段
flutter·electron·开源软件·ai编程·交友·im
JIngles1237 小时前
flutter避免对widget图片作重复刷新(含实际图片发生变化或不发生变化)
flutter
雾沉川11 小时前
Flutter 入门开发环境完整搭建教程
学习·flutter
MemoriKu12 小时前
Flutter 本地 AI 相册工程收口:从屏幕常亮、标签体系到照片属性后台队列
大数据·人工智能·python·flutter·elasticsearch·搜索引擎·数据库架构
Prowler_925614 小时前
创新项目实训博客(十一):大模型智能标题生成与多级降维兜底策略
人工智能·flutter·aigc
不良使15 小时前
鸿蒙PC迁移_LocalSend 迁移到鸿蒙 PC:一次 Flutter + Rust + 三方库适配的完整记录
flutter·rust·harmonyos
恋猫de小郭16 小时前
由于 iOS 26 的键盘变化,Flutter 又要重构键盘区域逻辑
android·前端·flutter
风华圆舞1 天前
在 Flutter 鸿蒙项目里接入文本转语音的完整思路
flutter·华为·harmonyos
勤劳打代码2 天前
翻江倒海——滚动布局下拉视图管理
flutter·前端框架·开源
spmcor2 天前
Flutter 学习笔记 (6):路由与导航 —— 从基础 push/pop 到 go_router
flutter