Flutter Dart线程模型及异常捕获F

查看原文Dart线程模型及异常捕获

Dart单线程模型

在Java和OC中,如果程序发生异常且没有被捕获,那么程序将会终止,但在Dart或JavaScript中则不会,究其原因,这和它们的运行机制有关系,Java和OC都是多线程模型的编程语言,任意一个线程触发异常且没被捕获时,整个进程就退出了。但Dart和JavaScript不同,它们都是单线程模型,运行机制很相似(但有区别),下面我们通过Dart官方提供的一张图来看看dart大致运行原理:

both-queues

Dart 在单线程中是以消息循环机制来运行的,其中包含两个任务队列,一个是“微任务队列” microtask queue,另一个叫做“事件队列” event queue。从图中可以发现,微任务队列的执行优先级高于事件队列。

现在我们来介绍一下Dart线程运行过程,如上图中所示,入口函数 main() 执行完后,消息循环机制便启动了。首先会按照先进先出的顺序逐个执行微任务队列中的任务,当所有微任务队列执行完后便开始执行事件队列中的任务,事件任务执行完毕后再去执行微任务,如此循环往复,生生不息。

在Dart中,所有的外部事件任务都在事件队列中,如IO、计时器、点击、以及绘制事件等,而微任务通常来源于Dart内部,并且微任务非常少,之所以如此,是因为微任务队列优先级高,如果微任务太多,执行时间总和就越久,事件队列任务的延迟也就越久,对于GUI应用来说最直观的表现就是比较卡,所以必须得保证微任务队列不会太长。值得注意的是,我们可以通过Future.microtask(…)方法向微任务队列插入一个任务。

在事件循环中,当某个任务发生异常并没有被捕获时,程序并不会退出,而直接导致的结果是当前任务的后续代码就不会被执行了,也就是说一个任务中的异常是不会影响其它任务执行的。

Flutter异常捕获

Dart中可以通过try/catch/finally来捕获代码块异常,这个和其它编程语言类似,,如果读者不清楚,可以查看Dart语言文档,不在赘述,下面我们看看Flutter中的异常捕获。

Flutter框架异常捕获

Flutter 框架为我们在很多关键的方法进行了异常捕获。这里举一个例子,当我们布局发生越界或不合规范时,Flutter就会自动弹出一个错误界面,这是因为Flutter已经在执行build方法时添加了异常捕获,最终的源码如下:

 
@override void performRebuild() { ... try { //执行build方法 built = build(); } catch (e, stack) { // 有异常时则弹出错误提示 built = ErrorWidget.builder(_debugReportException('building $this', e, stack)); } ... }

可以看到,在发生异常时,Flutter默认的处理方式是弹一个ErrorWidget,但如果我们想自己捕获异常并上报到报警平台的话应该怎么做?我们进入_debugReportException()方法看看:

 
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; }

 

我们发现,错误是通过FlutterError.reportError方法上报的,继续跟踪:


static void reportError(FlutterErrorDetails details) { ... if (onError != null) onError(details); //调用了onError回调 }

我们发现onErrorFlutterError的一个静态属性,它有一个默认的处理方法 dumpErrorToConsole,到这里就清晰了,如果我们想自己上报异常,只需要提供一个自定义的错误处理回调即可,如:

 
void main() { FlutterError.onError = (FlutterErrorDetails details) { reportError(details); }; ... }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值