flutter底层架构初探

打印 上一主题 下一主题

主题 564|帖子 564|积分 1692

本文出处:​​​​​​​​​​​​​Flutter 中文开发者网站 

架构


embedder嵌入层

提供程序入口(其他原生应用也采用此方式),程序由此和底层操作系统和谐(surface渲染、辅助功能和输入服务,管理事件循环队列)
嵌入层在android采用java和c++编写,苹果系采用object-c和object-C++,Windows和linux是c++
Engine引擎--核心

采用C++编写,提供了flutter应用所需的原语,核心api的底层实现
引擎将底层 C++ 代码包装成 Dart 代码,通过 dart:ui 袒露给 Flutter 框架层
增补:android和ios采用impeller渲染图形,其他平台采用skia(鸿蒙arkui也是使用的skia)
Framework框架层

开发者通过此层和flutter交互
build()方法

build方法就是将状态转换为ui的方法,widget重写该方法声明ui
此方法在框架需要时可以被调用,常规是一个渲染针一次
--得利于dart语言的可以快速实例化和扫除对象
应用根据事件交互,同道框架更换旧widget为新widget
flutter拥有本身的ui控制实现,而不是由系统自带的方法进行托管
Widget

flutter对于widget的准则是,widget由更小的用途单一的widget组成
两种核心的 widget 类:有状态的 和 无状态的 widget
widget 则需要被重建以更新相关部分的 UI。这些 widget 会继续 StatefulWidget,而且「可变的」状态会生存在继续 State 的另一个子类中(因为 widget 本身是不可变的)。 StatefulWidget 自身没有 build 方法,而在其对应的 State 对象中
每当你更改 State 对象时(例如计数增长),你需要调用 setState() 来告知框架,再次调用 State 的构建方法来更新 UI
将状态和 widget 对象分离,可以使其他 widget 无差异地看待无状态和有状态 widget,而不必担心丢失状态
渲染方式

react native等跨平台框架,一般在android和ios的ui底层库上创建一层抽象,使用js等代码与android和ios系统交互构建ui界面
flutter上文提到额,使用本身的widget,绘制flutter图像的dart代码被编译为机器码,并使用skia渲染
flutter嵌入了本身的skia副本,使得开发者可以不消最新的系统也能跟进系统升级跟新本身的应用
flutter绘制代码片段时,调用build方法返回一个基于当前状态的widget树,build方法会在须要时引入其他的widget--如指定color,coloredBox会被参加用于颜色布局
构建阶段,flutter将widgets转换为对应的element树
在渲染树中,每个节点的基类都是 RenderObject,该基类为布局和绘订界说了一个抽象模子。这是再寻常不过的事情:它并不总是一个固定的巨细,以致不遵循笛卡尔坐标规律(根据该 极坐标系的示例 所示)。每一个 RenderObject 都相识其父节点的信息,但对于其子节点,除了如何 访问 和获得他们的布局约束,并没有更多的信息。这样的设计让 RenderObject 拥有高效的抽象能力,能够处理处罚各种各样的使用场景。
在构建阶段,Flutter 会为 Element 树中的每个 RenderObjectElement 创建或更新其对应的一个从 RenderObject 继续的对象。 RenderObject 现实上是原语:渲染笔墨的 RenderParagraph、渲染图片的 RenderImage 以及在绘制子节点内容前应用变动的 RenderTransform 是更为上层的实现。
大部分的 Flutter widget 是由一个继续了 RenderBox 的子类的对象渲染的,它们呈现出的 RenderObject 会在二维笛卡尔空间中拥有固定的巨细。 RenderBox 提供了 盒子限制模子,为每个 widget 关联了渲染的最小和最大的宽度和高度。
平台嵌入层

平台嵌入层是flutter引擎一部分,充当宿主操作系统和flutter之间的粘合剂
开发者可以创建自界说的嵌入层,如:https://github.com/ardera/flutter-pi是支持树莓派运行的例子


与其他代码集成

flutter提供通过平台通道调用自界说代码的能力,
通过创建一个常用的通道(封装通道名称和编码),开发者可以在 Dart 与使用 Kotlin 和 Swift 等语言编写的平台组件之间发送和接收消息。数据会由 Dart 类型(例如 Map)序列化为一种尺度格式,然后反序列化为 Kotlin(例如 HashMap)大概 Swift(例如 Dictionary)中的等效类型。


外部函数接口

dart:ffi库提供了一套直接绑定原生代码的机制,比平台通道更快(不消序列化就可以传输数据)
flutter中渲染原生内容

flutter引入了平台widget办理在flutter应用展示原生组件的题目

现在桌面平台尚未支持平台视图,但这并不是一个架构层面的限制。未来大概将增长对桌面平台的支持
即成flutter widget至原生应用

Flutter 模块模板设计简朴,易于嵌入。开发者可以将其作为源代码依赖项集成到 Gradle 或 Xcode 构建界说中,大概将其打包成 Android Archive (AAR) 或 iOS Framework 二进制供其他开发者使用,而无需安装 Flutter。
Flutter 引擎需要一段短暂的时间做初始化,用于加载 Flutter 的共享库、初始化 Dart 的运行时、创建并运行 Dart isolate 线程并将渲染层与 UI 进行绑定。为了最大限度地减少呈现 Flutter 界面时的延迟,最好是在应用初始化时或至少在第一个 Flutter 页面展示前,一并初始化 Flutter 引擎,云云一来用户不会在首个 Flutter 页面加载时感到突然地卡顿。另外,Flutter 的引擎分离使得多个 Flutter 页面可以复用引擎,共享须要库加载时的内存消耗。
flutter对于web的支持

Dart 语言存在之初就已经支持直接编译成 JavaScript,而且针对开发和生产目的对其工具链进行了优化。许多告急的应用已经使用 Dart 编译成的 JavaScript 在生产环境上运行,包罗 Google Ads 的广告商工具。
然而,使用 C++ 编写的 Flutter 引擎是为了与底层操作系统进行交互的,而不是 Web 浏览器。因此我们需要另辟蹊径。Flutter 在 Web 平台上以浏览器的尺度 API 重新实现了引擎。现在我们有两种在 Web 上呈现内容的选项:HTML 和 WebGL。在 HTML 模式下,Flutter 使用 HTML、CSS、Canvas 和 SVG 进行渲染。而在 WebGL 模式下,Flutter 使用了一个编译为 WebAssembly 的 Skia 版本,名为 CanvasKit。 HTML 模式提供了最佳的代码巨细,CanvasKit 则提供了浏览器图形堆栈渲染的最快途径,并为原生平台的内容5提供了更高的图形保真度。

Flutter 框架本身和应用程序代码将一并编译成 JavaScript。同时Dart 在不同模式下(JIT 和 AOT、平台原生和 Web 编译)的语义险些没有差异,大部分开发者绝对可以无差异地编写这两种模式下的代码。
在进行开发时,Web 版本的 Flutter 使用支持增量编译的编译器 dartdevc 进行编译,以支持应用热重启(只管现在尚未支持热重载)。相反,当你准备好创建一个生产环境的 Web 应用时,Dart 深度优化的编译器 dart2js 将会用于编译,将 Flutter 核心框架和你的应用打包至缩小的源文件中,可摆设在任何服务器上。代码可以在单个文件中提供,也可拆分至多个文件以 延迟加载库 提供。



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

郭卫东

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表