flutter面试

Dart 相关

1、Dart 当中的 「..」表示什么意思?

级连操作符

“..” 和 “.” 不同:调用..后返回的相当于是 this,而.返回的则是该方

法返回的值;

2、Dart 的作用域是怎么样的?

Dart 没有 public 和 private 等关键词,默认就是公开的,私有变量使用下划

线开头;

4、dart 是多线程还是单线程执行?

单线程执行,多线程是使用异步来执行的;

5、阻塞式调用和非阻塞式调用是怎么样的?

阻塞:调用结果之前,当前线程会被挂起,调用线程只有在得到结果之后才会

继续执行;

非阻塞:调用执行之后,当前线程不会停止运行,只需要过一段时间来检查有

没有结果返回即可;

6、事件循环是什么?

将需要处理的一系列事件,放在一个事件队列(Event Queue)中,不断从事件

队列中取出事件,并执行需要执行的代码块,直到事件被清空。

7、dart 是值传递还是引用传递?

dart 是值传递。我们每次调用函数,传递过去的都是对象的内存地址,而不是

这个对象的复制。

8、Dart 语言有哪些重要的特性?

Productive(生产力高,Dart 的语法清晰明了,工具简单但功能强大)

Fast(执行速度快,Dart 提供提前优化编译,以在移动设备和 Web 上获

  得可预测的高性能和快速启动。)

Portable(易于移植,Dart 可编译成 ARM 和 X86 代码,这样 Dart 移动

应用程序可以在 iOS、Android 和其他地方运行)

Approachable(容易上手,充分吸收了高级语言特性,如果你已经知道

C++,C 语言,或者 Java,你可以在短短几天内用 Dart 来开发)

Reactive(响应式编程)

9、Dart 语言有哪些重要的概念?

在 Dart 中,一切都是对象,所有的对象都是继承自 Object

Dart 是强类型语言,但可以用 var 或 dynamic 来声明一个变量,Dart

会自动推断其数据类型,dynamic 类似 c#

没有赋初值的变量都会有默认值 null

Dart 支持顶层方法,如 main 方法,可以在方法内部创建方法

Dart 支持顶层变量,也支持类变量或对象变量

Dart 没有 public protected

private 等关键字,如果某个变量以下划线(_)开头,代表这个变量在库中是

私有的

10、Dart 线程模型是如何执行的?

Dart 是单线程模型,运行的的流程如下图。

Dart 在单线程中是以消息循环机制来运行的,包含两个任务队列,一个是“微

任务队列” microtask queue,另一个叫做“事件队列” event queue。 当Flutter 应用启动后,消息循环机制便启动了。首先会按照先进先出的顺序逐

个执行微任务队列中的任务,当所有微任务队列执行完后便开始执行事件队列

中的任务,事件任务执行完毕后再去执行微任务,如此循环往复,生生不息。

11、Dart 是如何实现多任务并行的?

Dart 是单线程的,不存在多线程,那如何进行多任务并行的呢?其实,Dart的多线程和前端的多线程有很多的相似之处。Flutter 的多线程主要依赖 Dart的并发编程、异步和事件驱动机制。

简单的说,在 Dart 中,一个 Isolate 对象其实就是一个 isolate 执行环境的引

用,一般来说我们都是通过当前的 isolate 去控制其他的 isolate 完成彼此之

间的交互,而当我们想要创建一个新的 Isolate 可以使用 Isolate.spawn 方法

获取返回的一个新的 isolate 对象,两个 isolate 之间使用 SendPort 相互发送

消息,而 isolate 中也存在了一个与之对应的 ReceivePort 接受消息用来处

理,但是我们需要注意的是,ReceivePort 和 SendPort 在每个 isolate 都有一

对,只有同一个 isolate 中的 ReceivePort 才能接受到当前类的 SendPort 发送

的消息并且处理。

12、await for 如何使用?

await for 是不断获取 stream 流中的数据,然后执行循环体中的操作。它一般

用在直到 stream 什么时候完成,并且必须等待传递完成之后才能使用,不然就

会一直阻塞。

13、Stream 有哪两种订阅模式?分别是怎么调用的?

单订阅(single)和多订阅(broadcast)。

单订阅就是只能有一个订阅者,而广播是可以有多个订阅者。这就有点类似于

消息服务(Message Service)的处理模式。单订阅类似于点对点,在订阅者出

现之前会持有数据,在订阅者出现之后就才转交给它。而广播类似于发布订阅

模式,可以同时有多个订阅者,当有数据时就会传递给所有的订阅者,而不管

当前是否已有订阅者存在。 Stream 默认处于单订阅模式,所以同一个 stream上的 listen 和其它大多数方法只能调用一次,调用第二次就会报错。但Stream 可以通过 transform() 方法(返回另一个 Stream)进行连续调用。通

过 Stream.asBroadcastStream() 可以将一个单订阅模式的 Stream 转换成一

个多订阅模式的 Stream,isBroadcast 属性可以判断当前 Stream 所处的模

式。

14、dart 中 mixin 机制是怎么样的?

mixin 是 Dart 2.1 加入的特性,以前版本通常使用 abstract class 代替。简

单来说,mixin 是为了解决继承方面的问题而引入的机制,Dart 为了支持多重

继承,引入了 mixin 关键字,它最大的特殊处在于:mixin 定义的类不能有构

造方法,这样可以避免继承多个类而产生的父类构造方法冲突。 mixins 的对

象是类,mixins 绝不是继承,也不是接口,而是一种全新的特性,可以 mixins多个类,mixins 的使用需要满足一定条件。

15、JIT 与 AOT 分别是什么?

借助于先进的工具链和编译器,Dart 是少数同时支持 JIT(Just In Time,即

时编译)和 AOT(Ahead of Time,运行前编译)的语言之一。那,到底什么是JIT 和 AOT 呢?语言在运行之前通常都需要编译,JIT 和 AOT 则是最常见的

两种编译模式。JIT 在运行时即时编译,在开发周期中使用,可以动态下发和

执行代码,开发测试效率高,但运行速度和执行性能则会因为运行时即时编译

受到影响。AOT 即提前编译,可以生成被直接执行的二进制代码,运行速度

快、执行性能表现好,但每次执行前都需要提前编译,开发测试效率低。

16、Dart 的内存分配与垃圾回收是怎么样的?

Dart VM 的内存分配策略比较简单,创建对象时只需要在堆上移动指针,内存

增长始终是线性的,省去了查找可用内存的过程。在 Dart 中,并发是通过Isolate 实现的。Isolate 是类似于线程但不共享内存,独立运行的 worker。

这样的机制,就可以让 Dart 实现无锁的快速分配。Dart 的垃圾回收,则是采

用了多生代算法。新生代在回收内存时采用“半空间”机制,触发垃圾回收

时,Dart 会将当前半空间中的“活跃”对象拷贝到备用空间,然后整体释放当

前空间的所有内存。回收过程中,Dart 只需要操作少量的“活跃”对象,没有

引用的大量“死亡”对象则被忽略,这样的回收机制很适合 Flutter 框架中大

量 Widget 销毁重建的场景。

17、使用 mixins 的条件是什么?

因为 mixins 使用的条件,随着 Dart 版本一直在变,这里讲的是 Dart2.1 中使

用 mixins 的条件:

mixins 类只能继承自 object mixins 类不能有构造函数

一个类可以 mixins 多个 mixins 类

可以 mixins 多个类,不破坏 Flutter 的单继承

18、mixin 怎么指定异常类型?

on 关键字可用于指定异常类型。 on 只能用于被 mixins 标记的类,例如mixins X on A,意思是要 mixins X 的话,得先接口实现或者继承 A。这里 A可以是类,也可以是接口,但是在 mixins 的时候用法有区别.

on 一个类:

on 的是一个接口: 得首先实现这个接口,然后再用 mix

19、main future mirotask 的执行顺序是怎样的?

普通代码都是同步执行的,结束后会开始检查 microtask 中是否有任务,若有

则执行,执行完继续检查 microtask,直到 microtask 列队为空。最后会去执

行 event 队列(future)。

20、Future 和 Isolate 有什么区别?

future 是异步编程,调用本身立即返回,并在稍后的某个时候执行完成时再获

得返回结果。在普通代码中可以使用 await 等待一个异步调用结束。 isolate是并发编程,Dart 有并发时的共享状态,所有 Dart 代码都在 isolate 中运

行,包括最初的 main()。每个 isolate 都有它自己的堆内存,意味着其中所有

内存数据,包括全局数据,都仅对该 isolate 可见,它们之间的通信只能通过

传递消息的机制完成,消息则通过端口(port)收发。isolate 只是一个概念,

具体取决于如何实现,比如在 Dart VM 中一个 isolate 可能会是一个线程,在Web 中可能会是一个 Web Worker。

21、Stream 与 Future 是什么关系?

Stream 和 Future 是 Dart 异步处理的核心 API。Future 表示稍后获得的一

个数据,所有异步的操作的返回值都用 Future 来表示。但是 Future 只能表

示一次异步获得的数据。而 Stream 表示多次异步获得的数据。比如界面上的

按钮可能会被用户点击多次,所以按钮上的点击事件(onClick)就是一个Stream 。简单地说,Future 将返回一个值,而 Stream 将返回多次值。Dart中统一使用 Stream 处理异步事件流。Stream 和一般的集合类似,都是一组数

据,只不过一个是异步推送,一个是同步拉取。

Flutter

1、介绍下 Flutter 的 FrameWork 层和 Engine 层,以及它们的作用

Flutter 的 FrameWork 层是用 Dart 编写的框架(SDK),它实现了一套基础

库,包含 Material(Android 风格 UI)和 Cupertino(iOS 风格)的 UI 界面,

下面是通用的 Widgets(组件),之后是一些动画、绘制、渲染、手势库等。

这个纯 Dart 实现的 SDK 被封装为了一个叫作 dart:ui 的 Dart 库。我们在使

用 Flutter 写 App 的时候,直接导入这个库即可使用组件等功能。 Flutter的 Engine 层是 Skia 2D 的绘图引擎库,其前身是一个向量绘图软件,Chrome和 Android 均采用 Skia 作为绘图引擎。Skia 提供了非常友好的 API,并且在

图形转换、文字渲染、位图渲染方面都提供了友好、高效的表现。Skia 是跨平

台的,所以可以被嵌入到 Flutter 的 iOS SDK 中,而不用去研究 iOS 闭源的Core Graphics / Core Animation。Android 自带了 Skia,所以 Flutter

Android SDK 要比 iOS SDK 小很多。

2、介绍下 Widget、State、Context 概念

• Widget:在 Flutter 中,几乎所有东西都是 Widget。将一个 Widget 想

象为一个可视化的组件(或与应用可视化方面交互的组件),当你需要

构建与布局直接或间接相关的任何内容时,你正在使用 Widget。

Widget 树:Widget 以树结构进行组织。包含其他 Widget 的 widget 被称

为父 Widget(或 widget 容器)。包含在父 widget 中的 widget 被称为子Widget。

Context:仅仅是已创建的所有 Widget 树结构中的某个 Widget 的位置引

用。简而言之,将 context 作为 widget 树的一部分,其中 context 所对

应的 widget 被添加到此树中。一个 context 只从属于一个 widget,它

和 widget 一样是链接在一起的,并且会形成一个 context 树。

State:定义了 StatefulWidget 实例的行为,它包含了用于”交互/干预

“Widget 信息的行为和布局。应用于 State 的任何更改都会强制重建Widget。

3、介绍下 StatelessWidget 和 StatefulWidget 两种状态组件类

StatelessWidget: 一旦创建就不关心任何变化,在下次构建之前都不会

改变。它们除了依赖于自身的配置信息(在父节点构建时提供)外不再

依赖于任何其他信息。比如典型的 Text、Row、Column、Container 等,

都是 StatelessWidget。它的生命周期相当简单:初始化、通过 build()渲染。

StatefulWidget: 在生命周期内,该类 Widget 所持有的数据可能会发生

变化,这样的数据被称为 State,这些拥有动态内部数据的 Widget 被称

为 StatefulWidget。比如复选框、Button 等。State 会与 Context 相关

联,并且此关联是永久性的,State 对象将永远不会改变其 Context,即

使可以在树结构周围移动,也仍将与该 context 相关联。当 state 与context 关联时,state 被视为已挂载。StatefulWidget 由两部分组

成,在初始化时必须要在 createState()时初始化一个与之相关的 State对象。

4、StatefulWidget 的生命周期是怎么样的?

Flutter 的 Widget 分为 StatelessWidget 和 StatefulWidget 两种。其中,StatelessWidget 是无状态的,StatefulWidget 是有状态的,因此实际使用

时,更多的是 StatefulWidget。StatefulWidget 的生命周期如下图

initState():Widget 初始化当前 State,在当前方法中是不能获取到Context 的,如想获取,可以试试 Future.delayed()

didChangeDependencies():在 initState() 后调用,State 对象依赖

关系发生变化的时候也会调用。

deactivate():当 State 被暂时从视图树中移除时会调用这个方法,页

面切换时也会调用该方法,和 Android 里的 onPause 差不多。

dispose():Widget 销毁时调用。didUpdateWidget:Widget 状态发生变化的时候调用。

5、说下 Widgets、RenderObjects 和 Elements 的关系

首先看一下这几个对象的含义及作用。

Widget :仅用于存储渲染所需要的信息。

RenderObject :负责管理布局、绘制等操作。

Element :才是这颗巨大的控件树上的实体。

Widget 会被 inflate(填充)到 Element,并由 Element 管理底层渲染树。Widget 并不会直接管理状态及渲染,而是通过 State 这个对象来管理状态。Flutter 创建 Element 的可见树,相对于 Widget 来说,是可变的,通常界面开

发中,我们不用直接操作 Element,而是由框架层实现内部逻辑。就如一个 UI视图树中,可能包含有多个 TextWidget(Widget 被使用多次),但是放在内部视

图树的视角,这些 TextWidget 都是填充到一个个独立的 Element 中。Element会持有 renderObject 和 widget 的实例。记住,Widget 只是一个配置,RenderObject 负责管理布局、绘制等操作。 在第一次创建 Widget 的时候,

会对应创建一个 Element, 然后将该元素插入树中。如果之后 Widget 发生了

变化,则将其与旧的 Widget 进行比较,并且相应地更新 Element。重要的

是,Element 不会被重建,只是更新而已。

6、Flutter 是如何与原生 Android、iOS 进行通信的?

Flutter 通过 PlatformChannel 与原生进行交互,其中 PlatformChannel 分

为三种:

• BasicMessageChannel:用于传递字符串和半结构化的信息。

MethodChannel:用于传递方法调用。Flutter 主动调用 Native 的方

  法,并获取相应的返回值。

EventChannel:用于数据流(event streams)的通信。

关于原理:www.jianshu.com/p/39575a90e...

7、简述下 Flutter 的热重载

Flutter 的热重载是基于 JIT 编译模式的代码增量同步。由于 JIT 属于动态

编译,能够将 Dart 代码编译成生成中间代码,让 Dart VM 在运行时解释执

行,因此可以通过动态更新中间代码实现增量同步。

热重载的流程可以分为 5 步,包括:扫描工程改动、增量编译、推送更新、代

码合并、Widget 重建。

Flutter 在接收到代码变更后,并不会让 App 重新启动执行,而只会触发Widget 树的重新绘制,因此可以保持改动前的状态,大大缩短了从代码修改到

看到修改产生的变化之间所需要的时间。

另一方面,由于涉及到状态的保存与恢复,涉及状态兼容与状态初始化的场

景,热重载是无法支持的,如改动前后 Widget 状态无法兼容、全局变量与静

态属性的更改、main 方法里的更改、initState 方法里的更改、枚举和泛型的

更改等。

可以发现,热重载提高了调试 UI 的效率,非常适合写界面样式这样需要反复

查看修改效果的场景。但由于其状态保存的机制所限,热重载本身也有一些无

法支持的边界。

8、说下 Flutter 和其他跨平台方案的本质区别

React Native 之类的框架,只是通过 JavaScript 虚拟机扩展调用系统组件,

由 Android 和 iOS 系统进行组件的渲染;

Flutter 则是自己完成了组件渲染的闭环。那么,Flutter 是怎么完成组件渲

染的呢?这需要从图像显示的基本原理说起。在计算机系统中,图像的显示需

要 CPU、GPU 和显示器一起配合完成:CPU 负责图像数据计算,GPU 负责图像

数据渲染,而显示器则负责最终图像显示。CPU 把计算好的、需要显示的内容

交给 GPU,由 GPU 完成渲染后放入帧缓冲区,随后视频控制器根据垂直同步信

号(VSync)以每秒 60 次的速度,从帧缓冲区读取帧数据交由显示器完成图像

显示。操作系统在呈现图像时遵循了这种机制,而 Flutter 作为跨平台开发框

架也采用了这种底层方案。下面有一张更为详尽的示意图来解释 Flutter 的绘

制原理。

Flutter 绘制原理可以看到,Flutter 关注如何尽可能快地在两个硬件时钟的VSync 信号之间计算并合成视图数据,然后通过 Skia 交给 GPU 渲染:UI 线

程使用 Dart 来构建视图结构数据,这些数据会在 GPU 线程进行图层合成,随

后交给 Skia 引擎加工成 GPU 数据,而这些数据会通过 OpenGL 最终提供给GPU 渲染。

9、Widget 唯一标识 Key 有哪几种?

在 flutter 中,每个 widget 都是被唯一标识的。这个唯一标识在 build 或rendering 阶段由框架定义。该标识对应于可选的 Key 参数,如果省略,Flutter 将会自动生成一个。

在 flutter 中,主要有 4 种类型的 Key:GlobalKey(确保生成的 Key 在整个应

用中唯一,是很昂贵的,允许 element 在树周围移动或变更父节点而不会丢失

状态)、LocalKey、UniqueKey、ObjectKey。

10、什么是 Navigator? MaterialApp 做了什么?

Navigator 是在 Flutter 中负责管理维护页面堆栈的导航器。MaterialApp 在需要的时候,会自动为我们创建 Navigator。

Navigator.of(context),会使用 context 来向上遍历 Element 树,找到MaterialApp 提供的_NavigatorState 再调用其 push/pop 方法完成导航操作。

11、Flutter 动画类型有哪些?

补间动画:给定初值与终值,系统自动补齐中间帧的动画

物理动画:遵循物理学定律的动画,实现了弹簧、阻尼、重力三种物理

  效果

在应用使用过程中常见动画模式:

动画列表或者网格:例如元素的添加或者删除操作;

转场动画 Shared element transition:例如从当前页面打开另一页面

的过渡动画;

交错动画 Staggered animations:比如部分或者完全交错的动画。

12、Flutter 是怎么完成组件渲染的?

A:

13、Flutter 绘制流程是怎么样的?

A:

14、如何统一管理错误页面?

在 main 方法修改 ErrorWidget.builder 来自定义一个属于自己的 Widget;

如:

/// 自定义报错页面

ErrorWidget.builder = (FlutterErrorDetails flutterErrorDetails) {

    debugPrint(flutterErrorDetails.toString());

return new Center(child: new Text("App 错误,快去反馈给作者!"));

};

复制代码

15、Flutter 中存在哪四大线程?

Flutter 中存在四大线程,分别为 UI Runner、GPU Runner、IO Runner,Platform Runner (原生主线程) ,同时在 Flutter 中可以通过 isolate 或

者 compute 执行真正的跨线程异步操作。

16、PlatformView 的作用有哪些?

Flutter 中通过 PlatformView 可以嵌套原生 View 到 Flutter UI 中;

17、PlatformView 使用了哪些东西来实现?

Presentation、VirtualDisplay 、 Surface 等;

18、PlatformView 大致原理是怎么样的?

使用了类似副屏显示的技术,VirtualDisplay 类代表一个虚拟显示器,调用DisplayManager 的 createVirtualDisplay() 方法,将虚拟显示器的内容渲染

在一个 Surface 控件上,然后将 Surface 的 id 通知给 Dart,让 engine 绘

制时,在内存中找到对应的 Surface 画面内存数据,然后绘制出来。 实时控

件截图渲染显示技术。

19、Flutter 的 Debug 和 release 分别是在什么模式下运行的?

Flutter 的 Debug 下是 JIT 模式,release 下是 AOT 模式。

20、Platform Channel 有哪几种通信方式?分别是用于什么操作?

BasicMessageChannel :用于传递字符串和半结构化的信息。

MethodChannel :用于传递方法调用(method invocation)。

EventChannel: 用于数据流(event streams)的通信。

21、RenderObject 布局相关方法调用顺序是怎么样的?

layout -> performResize -> performLayout -> markNeedsPaint , 但是用户

一般不会直接调用 layout,而是通过 markNeedsLayout ,具体流程如下:

22、RenderObject 如何使得页面重绘?流程是怎么样的?

RenderObject 在 attch/layout 之后会通过 markNeedsPaint(); 使得页面重

绘,流程大概如下:

通过 isRepaintBoundary 往上确定了更新区域,通过 requestVisualUpdate方法触发更新往下绘制。

23、Flutter 存在哪几棵树?他们有什么关系?

Flutter 中存在 Widget 、 Element 、RenderObject 、Layer 四棵树,其中Widget 与 Element 是一对多的关系 ,

24、简述下 Flutter 的线程管理模型

默认情况下,Flutter Engine 层会创建一个 Isolate,并且 Dart 代码默认就运

行在这个主 Isolate 上。必要时可以使用 spawnUri 和 spawn 两种方式来创建新

的 Isolate,在 Flutter 中,新创建的 Isolate 由 Flutter 进行统一的管理。

事实上,Flutter Engine 自己不创建和管理线程,Flutter Engine 线程的创建

和管理是 Embeder 负责的,Embeder 指的是将引擎移植到平台的中间层代码,Flutter Engine 层的架构示意图如下图所示。

在 Flutter 的架构中,Embeder 提供四个 Task Runner,分别是 Platform Task

Runner、UI Task Runner Thread、GPU Task Runner 和 IO Task Runner,每个Task Runner 负责不同的任务,Flutter Engine 不在乎 Task Runner 运行在哪

个线程,但是它需要线程在整个生命周期里面保持稳定

状态管理 【来自老友:i 校长】1、状态管理是什么?

程序=算法+数据结构 数据是程序的中心。数据结构和算法两个概念间的逻辑关

系贯穿了整个程序世界,首先二者表现为不可分割的关系。其实 Flutter 不就

是一个程序吗,那我们面临的最底层的问题还是算法和数据结构,所以我们推

导出

Flutter=算法+数据结构 那状态管理是什么?我也用公式来表达一下,如下:Flutter 状态管理=算法+数据结构+UI 绑定

2、为什么需要状态管理?

用于解决状态更新问题,不需要 WidgetState 被全局化,保证组件隐私,使得

代码可扩展,易维护,可以动态替换 UI 而不影响算法逻辑,安全可靠,保持数

据的稳定伸缩,性能佳,局部优化;

3、说下状态管理基本分类

分为局部管理和全局管理;

局部管理:短暂的状态,这种状态根本不需要做全局处理;

全局管理:即应用状态,非短暂状态,您要在应用程序的许多部分之间

共享,以及希望在用户会话之间保持的状态,就是我们所说的应用程序

  状态(有时也称为共享状态)

4、状态管理的底层逻辑一般是怎么样的?

State:如 StatefulWidget、StreamBuilder 状态管理方式;

InheritedWidget 专门负责 Widget 树中数据共享的功能型 Widget:如

Provider、scoped_model 就是基于它开发;

Notification:与 InheritedWidget 正好相反,InheritedWidget 是从

上往下传递数据,Notification 是从下往上,但两者都在自己的 Widget树中传递,无法跨越树传递;

Stream 数据流 :如 Bloc、flutter_redux、fish_redux 等也都基于它

来做实现;

5、状态管理的使用原则是怎么样的?

局部管理优于全局、保持数据安全性、考虑页面重新 build 带来的影响;

6、使用成熟状态管理库的弊端有哪些?

增加代码复杂性、框架 bug 修复需要时间等待、不理解框架原理导致使用方式

不对,反而带来更多问题、选型错误导致不符合应用要求、与团队风格冲突不

适用;

进阶

1、flutter run 实际走了哪三个命令?分别用于什么操作?

flutter build apk:通过 gradle 来构建 APK

adb install:安装 APK

adb am start:启动应用

2、Flutter 引擎启动过程中做了什么操作?3、setState 做了哪些工作?是如何更新 UI 的?

setState 其实是调用了 markNeedsBuild ,该方法内部标记此 Element 为Dirty ,然后在下一帧 WidgetsBinding.drawFrame 才会被绘制, setState并不是立即生效的。

4、Flutter 应用启动 runApp(MyApp)过程是怎么样的?

Flutter 中 runApp 启动入口其实是一个 WidgetsFlutterBinding ,它主要是

通过 BindingBase 的子类 GestureBinding 、ServicesBinding 、SchedulerBinding 、PaintingBinding 、SemanticsBinding 、RendererBinding 、WidgetsBinding 等,通过 mixins 的组合而成的。

5.Dart 虚拟机如何管理的?怎么调用?如何跟 Flutter 引擎交互?

Dart 虚拟机拥有自己的 Isolate,完全由虚拟机自己管理的,Flutter 引擎也

无法直接访问。Dart 的 UI 相关操作,是由 Root Isolate 通过 Dart 的 C++调

用,或者是发送消息通知的方式,将 UI 渲染相关的任务提交到 UIRunner 执

行,这样就可以跟 Flutter 引擎相关模块进行交互。

6、Isolate 组成部分有哪些?分别有什么作用?

isolate 堆是运该 isolate 中代码分配的所有对象的 GC 管理的内存存

储;

vm isolate 是一个伪 isolate,里面包含不可变对象,比如 null,true,false;

isolate 堆能引用 vm isolate 堆中的对象,但 vm isolate 不能引用isolate 堆;

isolate 彼此之间不能相互引用 每个 isolate 都有一个执行 dart 代码

的 Mutator thread,一个处理虚拟机内部任务(比如 GC, JIT 等)的helper thread;

7、线程和 isolate 的关系是什么?

1、同一个线程在同一时间只能进入一个 isolate,当需要进入另一个 isolate则必须先退出当前的 isolate;

2、一次只能有一个 Mutator 线程关联对应的 isolate,Mutator 线程是执行Dart 代码并使用虚拟机的公共的 C 语言 API 的线程;

8、介绍下 JIT 运行模式中 kernel service

是一个辅助类 isolate,其核心工作就是 CFE,将 dart 转为 Kernel 二进制,然

后 VM 可直接使用 Kernel 二进制运行在主 isolate 里面运行。

9、介绍下 Dart 虚拟机中通过 Snapshots 运行

A:

10、介绍下 Dart 虚拟机中通过 AppAOT Snapshots 运行

A:

11、图片加载流程是怎么样的?

A:

12、简单的说下 GestureDector 底层实现

A:

13、setState 在哪种场景下可能会失效?

1、刷新方法内声明的变量;2、刷新被 final 修饰的变量;

14、isolate 是怎么进行通信的?实例化过程是怎么样的?

isolate 线程之间的通信主要通过 port 来进行,这个 port 消息传递过程是异

步的。

实例化一个 isolate 的过程包括:

1.实例化 isolate 结构体。

2.在堆中分配线程内存。

3.配置 port 等过程。

15、虚拟机如何运行 Dart 代码?

1.源码或者 Kernel 二进制(JIT)

2.snapshot :

AOT snapshot

AppJIT snapshot

16、JIT 运行模式中 debug 运行原理是怎么样的?

将 dart 代码转换为 kernel 二进制和执行 kernel 二进制,这两个过程也可以分

离开来,在两个不同的机器执行,比如 host 机器执行编译,移动设备执行kernel 文件。

17.默认情况下 debug 和 release 会生成哪些架构的 so 库?

图解:

这个编译过程并不是 flutter tools 自身完成,而是交给另一个进程frontend_server 来执行,它包括 CFE 和一些 flutter 专有的 kernel 转换器。hot reload:热重载机制正是依赖这一点,frontend_server 重用上一次编译

中的 CFE 状态,只重新编译实际更改的部分。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容