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 的稳定性,减少崩溃情况。

相关推荐
恋猫de小郭4 小时前
Flutter 小技巧之通过 MediaQuery 优化 App 性能
android·前端·flutter
顾林海8 小时前
Flutter Dart 流程控制语句详解
android·前端·flutter
pengyu12 小时前
系统化掌握Flutter组件之Dismissible
android·flutter·dart
pengyu14 小时前
系统化掌握Flutter组件之Draggable/DragTarget
android·flutter·dart
strongs15 小时前
开源一个两年前写的flutter的K线分时图
flutter
moton20171 天前
Flutter开发避坑指南:高频问题排查与性能调优实战
mqtt·flutter·性能优化·前端框架·自动化·dart
云水-禅心1 天前
Flutter中网络图片加载显示Image.network的具体用法
flutter
云水-禅心1 天前
flutter的HTTP headers用法介绍
flutter·httpclient
前端 贾公子1 天前
Vue.js 3 的设计思路:从声明式UI到高效渲染机制
vue.js·flutter·ui
帅次2 天前
Flutter:StatelessWidget vs StatefulWidget 深度解析
android·flutter·ios·小程序·swift·webview·android-studio