Dart单线程模型
Dart 在单线程中是以消息循环机制来运行的,其中包含两个任务队列,一个是“微任务队列” microtask queue,另一个叫做“事件队列” event queue。微任务队列的执行优先级高于事件队列。
在事件循环中,当某个任务发生异常并没有被捕获时,程序并不会退出,而直接导致的结果是当前任务的后续代码就不会被执行了,也就是说一个任务中的异常是不会影响其他任务执行的
Flutter框架异常捕获
Flutter的异常分两类:同步异常和异步异常,同步异常可以通过try/catch捕获。
异步异常使用Zone.runZoned方法进行进行捕获。 Flutter使用 try {}catch(e,stack){}进行异常捕获。
同步异常
try {
built = build();
} catch (e, stack) {
// 有异常时则弹出错误提示
built = ErrorWidget.builder(_debugReportException('building $this', e, stack));
}
FlutterErrorDetails _debugReportException(
String context,
dynamic exception,
StackTrace stack, {
InformationCollector informationCollector
}) {
//构建错误详情对象
final FlutterErrorDetails details = FlutterErrorDetails(
exception: exception,
stack: stack,
library: 'widgets library',
context: context,
informationCollector: informationCollector,
);
//报告错误
FlutterError.reportError(details);
return details;
}
通过_debugReportException发现使用FlutterError.reportError(details),进行异常上报。
处理flutter同步整体异常,在app入口的main方法中添加
FlutterError.onError = (FlutterErrorDetails details) {
//获取所有同步异常,显示或者上报异常信息
};
异步异常处理
处理异步监听flutter同步整体异常,在app入口的main方法中添加Zone.runZoned。
我们可以给代码执行对象指定一个 Zone,在 Dart 中,Zone 表示一个代码执行的环境范围,其概念类似沙盒,不同沙盒之间是互相隔离的。如果我们想要观察沙盒中代码执行出现的异常,沙盒提供了 onError 回调函数,拦截那些在代码执行对象中的未捕获异常
runZoned(
() => runApp(MyApp()),
zoneSpecification: ZoneSpecification(
// 拦截print
print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
collectLog(line);
parent.print(zone, "Interceptor: $line");
},
// 拦截未处理的异步错误
handleUncaughtError: (Zone self, ZoneDelegate parent, Zone zone,
Object error, StackTrace stackTrace) {
reportErrorAndLog(details);
parent.print(zone, '${error.toString()} $stackTrace');
},
),
);
//或者使用
//在Flutter开发通常使用此方法
runZonedGuarded(
() {
runApp(MyApp());
},
(error, stackTrace) {
//没被我们catch的异常
reportErrorAndLog(makeDetails(error, stackTrace));
},
);