引言
说到Flutter,绝对绕不开Fuchsia,这个是谷歌开发的一款全新的操作系统Fuchsia内核是Magenta Kernel,一个基于LittleKernel的项目。该系统与Android相比,无论是存储器还是内存之类的硬件要求都大幅降低,外界推论是一款面向物联网的系统,具体是做什么的目前不得而知,但这不是我们所讲的重点
What Is Flutter?
官方介绍
- 快速开发:Flutter的热重载可以快速地进行测试、构建UI、添加功能并更快地修复错误。
- 富有表现力,漂亮的用户界面:自带的Material Design和Cupertino(iOS风格)widget、丰富的motion API、平滑而自然的滑动效果。
- 响应式框架:使用Flutter的现代、响应式框架,和一系列基础widget,轻松构建您的用户界面。
- 访问本地功能和SDK:Flutter可以复用现有的Java、Swift或ObjC代码,访问iOS和Android上的原生系统功能和系统SDK。
- 统一的应用开发体验:Flutter拥有丰富的工具和库,可以帮助开发者轻松地同时在iOS和Android系统中实现想法和创意。
- 原生性能:Flutter包含了许多核心的widget,如滚动、导航、图标和字体等,这些都可以在iOS和Android上达到原生应用一样的性能。
定义
Flutter是Google一个新的用于构建跨平台的手机App的SDK
跨平台应用的框架,没有使用WebView或者系统平台自带的控件,使用自身的高性能渲染引擎自绘
简化版的浏览器,最大限度在android和ios上统一UI,包括业务逻辑和用户体验
开发语言使用dart,结合C, C++, 和Skia(2D渲染引擎)构建
支持hot reload,包含着完整的控件和工具链
一切皆控件,控件是每个Flutter应用程序的基本构建块,与分离视图、控制器、布局和其他属性的框架不同,Flutter具有一致的统一对象模型:控件。一个控件可以定义:结构元素(比如按钮或菜单)、风格元素(比如字体或颜色方案)、布局的方面(比如填充)、一些业务逻辑等
组合大于继承,控件本身通常由许多小型、单用途的控件组成,结合起来产生强大的效果,类的层次结构是扁平的,以最大化可能的组合数量
强化版的WebView,框架仅提供一个View层,大部分功能要依赖原生
目前只能够运行大部分Dart代码(不能引入dart:mirrors或dart:html库)
核心原则
Flutter 包含了一个函数响应式框架( functional-reactive framework)、一个 2D 渲染引擎、直接可用的 Widget 库、和各种开发工具。这些组件在一起配合使用,来帮助你设计、开发、测试和调试 应用。这些功能都围绕几个核心的原则来实现的。
Why Flutter?
高生产率
- 一套代码可以开发出 Android 和 iOS 应用
- 同样的功能只需要很少的代码,如果你只开发一个平台的应用,使用 时髦的、更具有表达性的开发语言,也可以让你用更少的代码来实现同样的功能。
- 开发原型和迭代更加方便
- 在 应用运行的时候就可以修改代码并重新加载修改后的功能
- 直接修改崩溃的 bug,然后继续从崩溃的地方执行调试
创建优雅的、可定制的用户界面
- Flutter 内置了对纸墨设计(Material Design)的支持,提供了丰富的 UI 控件库可以用来创建纸墨设计风格的 UI
- 提供了可定制的 UI 框架,不再受制于手机平台控件的支持
Flutter SDK体积为什么非常大?
- Flutter应用的体积由两部分组成:应用代码和 SDK代码。应用代码是 Dart编译后的代码,如果做成可动态下发,那么这部分可以不计。 SDK代码比较大就有点无奈了,SDK的组成部分有 Dart VM,Dart标准库,libwebp、libpng、libboringssl等第三方库,libskia,Dart UI库,然后再加上 icu_data,可能在单 arch下(iOS),SDK体积达到 40+MB。其中仅仅 Dart VM(不包含标准库)就达到了 7MB。 Flutter SDK是 dynamic framework,如此大的二进制体积可能会造成动态链接耗时长。而如果静态链接,可能原来比较大的 App很有可能造成 TEXT段超标。
How Flutter?
运行机制
Flutter 应用运行在一个用 C++ 写的引擎中,Flutter 应用可以看做是一个游戏 App,代码都是在引擎中运行。
Android
引擎的C或C++代码是由Android NDK编译的,而框架的主要代码和应用的代码由Dart compiler编译成native code执行的。
对于Android应用来说,Flutter框架在引擎中实现了一个继承于SurfaceView的 FlutterView。用户所看到的UI都是在这个SurfaceView中显示。如果要和原生平台功能交互,则可以在Activity中使用FlutterView,并通过Flutter提供的消息API和原生平台收发消息。
ios
- 引擎的C或C++代码是由LLVM编译的,而所有Dart的代码会被AOT编译成native code,整个APP运行时使用的是机器指令(并不是拦截器)。
系统架构
Flutter Framework: 这是一个纯 Dart实现的 SDK,类似于 React在 JavaScript中的作用。它实现了一套基础库, 用于处理动画、绘图和手势。并且基于绘图封装了一套 UI组件库,然后根据 Material 和Cupertino两种视觉风格区分开来。这个纯 Dart实现的 SDK被封装为了一个叫作 dart:ui的 Dart库。我们在使用 Flutter写 App的时候,直接导入这个库即可使用组件等功能。
-
Flutter Engine: 这是一个纯 C++实现的 SDK,其中囊括了 Skia引擎、Dart运行时、文字排版引擎等。不过说白了,它就是 Dart的一个运行时,它可以以 JIT、JIT Snapshot 或者 AOT的模式运行 Dart代码。在代码调用 dart:ui库时,提供 dart:ui库中 Native Binding 实现。 不过别忘了,这个运行时还控制着 VSync信号的传递、GPU数据的填充等,并且还负责把客户端的事件传递到运行时中的代码。
-
整个 Flutter Engine可以粗略地划分为三个部分:Dart UI、Runtime、Shell
绘制流程
入口
- 界面的布局和绘制在每一帧都在发生着,甚至界面没有变化,它也会存在;可以想象每一帧里面,引擎都像流水线的一样重复着几个过程:build(构建控件树),layout(布局), paint(绘制)和 composite(合成),周而复始。驱动整个流水线的入口是WidgetBinding.drawFrame方法。
void drawFrame() {
...
try {
if (renderViewElement != null)
buildOwner.buildScope(renderViewElement);
super.drawFrame();
buildOwner.finalizeTree();
} finally {
...
}
...
}
布局约束
- 根据parent给予的约束条件来计算size,而设置size只能在performResize或者performLayout中进行,如果设置sizedByParent为true,则只能在performResize中进行,否则就只能在performLayout中与child的布局同时进行。