Flutter

Flutter 介绍
Flutter app 使用了 Dart 语言,源自于 Google,现在是 ECMA 的标准。Dart 吸收了许多现代语言的特性,比如 Kotlin 和 Swift,同时能被转译成 js 代码。

作为一个跨平台框架,Flutter 和 React Native 非常像,因为 Flutter 支持响应式和声明式语法。但和 React Native 不同,Flutter 不需要 Javascript 桥接,这显著提升了 app 的加载时间和整体性能。Dart 是通过 AOT 编译来做到这一点的。
Dart 还有一个独特的地方,它也支持 JIT 编译。Flutter 的 JIT 编译改变了开发流程,它允许在开发中通过热加载来更新 UI,而无需进行新的 build。

配置开发环境
创建项目
热加载
导入文件和包
widget 的创建和使用
网络调用
在列表中显示内容
添加 app 主题

同时,你还会学到一点 Dart :]


Flutter 的两种编译模式:
编译模式的分类
编程语言要达到可运行的目的需要经过编译,一般地来说,编译模式分为两类:JIT 和 AOT。
JIT:
JIT 全称 Just In Time (即时编译),典型的例子就是 v8,它可以即时编译并运行 JavaScript。所以你只需要输入源代码字符串,v8 就可以帮你编译并运行代码。通常来说,支持 JIT 的语言一般能够支持自省函数(eval),在运行时动态地执行代码。
JIT 模式的优势是显而易见的,可以动态下发和执行代码,而不用管用户的机器是什么架构,为应用的用户提供丰富而动态地内容。
但 JIT 的劣势也是显而易见的,大量字符串的代码很容易让 JIT 编译器花费很多时间和内存进行编译,给用户带来的直接感受就是应用启动慢。
V8 (JavaScript引擎)

AOT:
AOT 全称 Ahead Of Time(事前编译)
AOT 全称 Ahead Of Time(事前编译),典型的例子就是 C/C++,LLVM 或 GCC 通过编译并生成 C/C++ 的二进制代码,然后这些二进制通过用户安装并取得执行权限后才可以通过进程加载执行。
AOT 的优势也是显而易见的,事先编译好的二进制代码,加载和执行的速度都会非常快。(所以编程语言速度排行榜上前列都是 AOT 编译类语言)这样的速度可以在密集计算场景下给用户带来非常好的体验,比如大型游戏的引擎渲染和逻辑执行。但是 AOT 的劣势也是显而易见的,编译需要区分用户机器的架构,生成不同架构的二进制代码。除了架构,二进制代码本身也会让用户下载的安装包比较大。二进制代码一般需要取得执行权限才可以执行,所以无法在权限比较严格的系统中进行动态更新(如 iOS)。

Dart的编译模式:
Flutter 使用 Dart 作为编程语言,自然其编译模式也脱离不了 Dart 的干系。首先我们需要了解一下 Dart 所支持的编译模式。
Script:最普通的 JIT 模式,在 PC 命令行调用 Dart VM 执行 Dart 源代码文件即是这种模式;
Script Snapshot:JIT 模式,和上一个不同的是,这里载入的是已经 token 化的 Dart 源代码,提前执行了上一步的lexer 步骤;
Application Snapshot:JIT 模式,这种模式来源于 Dart VM 直接载入源码后 dump 出数据。Dart VM
通过这种数据启动会更快。不过值得一提的是这种模式是区分架构的,在 x64 上生成的数据不可以给 arm 使用;

AOT:AOT模式,直接将 Dart 源码编译出 .S 文件,然后通过汇编器生成对应架构的代码。

Flutter的编译模式:

Flutter 完全采用了 Dart,按道理来说编译模式一致才是,但是事实并不是这样。由于 Android 和 iOS平台的生态差异,Flutter 也衍生出了非常丰富的编译模式。
Script:同 Dart Script 模式一致,虽然 Flutter 支持,但暂未看到使用,毕竟影响启动速度;
Script Snapshot:同 Dart Script Snapshot 一致,同样支持但未使用,Flutter
有大量的视图渲染逻辑,纯 JIT 模式影响执行速度;
Kernel Snapshot: Dart 的 bytecode模式,与 Application Snapshot 不同,bytecode
模式是不区分架构的。Kernel Snapshot 在 Flutter 项目内也叫 Core Snapshot。bytecode模式可以归类为 AOT 编译;
Core JIT:Dart 的一种二进制模式,将指令代码和 heap 数据打包成文件,然后在 VM 和 isolate
启动时载入,直接标记内存可执行,可以说这是一种 AOT 模式。Core JIT 也被叫做 AOTBlob;
AOT Assembly: 即 Dart 的 AOT 模式。直接生成汇编源代码文件,由各平台自行汇编。

开发阶段的编译模式:
在开发阶段,我们需要 Flutter 的 Hot Reload 和 Hot Restart 功能,方便 UI 快速成型。同时,框架层也需要比较高的性能来进行视图渲染展现。因此开发模式下,Flutter 使用了 Kernel Snapshot 模式编译。

在打包产物中,你将发现几样东西:
isolate_snapshot_data:用于加速 isolate 启动,业务无关代码,固定,仅和 flutter engine
版本有关;
platform.dill:和 Dart VM 相关的 kernel 代码,仅和 Dart 版本以及 engine
编译版本有关。固定,业务无关代码;
vm_snapshot_data: 用于加速 Dart VM 启动的产物,业务无关代码,仅和 flutter engine 版本有关;
kernel_blob.bin:业务代码产物

生产阶段的编译模式:
在生产阶段,应用需要的是非常快的速度,所以 Android 和 iOS target 毫无意外地都选择了 AOT 打包。不过由于平台特性不同,打包模式也是天壤之别。

首先我们很容易认识到 iOS 平台上做法的原因:App Store 审核条例不允许动态下发可执行二进制代码。

所以在 iOS 上,除了 JavaScript,其他语言运行时的实现都选择了 AOT(比如 OpenJDK 在 iOS 实现就是 AOT)。

在 Android 上,Flutter 的做法有点意思:支持了两种不同的路子。
Core JIT 的打包产物有 4 个:isolate_snapshot_data、vm_snapshot_data、isolate_snapshot_instr、vm_snapshot_instr。我们不认识的产物只有 2 个:isolate_snapshot_instr 和 vm_snapshot_instr,其实它俩代表着 VM 和 isolate 启动后所承载的指令等数据。在载入后,直接将该块内存执行即可。
Android 的 AOT Assembly 打包方式很容易让人想到需要支持多架构,无疑增大了代码包,并且该处代码需要从 JNI 调用,远不如 Core JIT 的 Java API 方便。所以 Android 上默认使用 Core JIT 打包,而不是 AOT Assembly。
总结:
Flutter 是一种高性能的、可跨平台的、动态化应用开发方案。
在 iOS 和 Android 平台上,动态化完全可由 Kernel Snapshot 打包实现,并且产物是一致通用的。不过目前通过打包工具进行了阉割,只能生成 debug 产物。

并且如果不需要动态化,同样可以打包出拥有更高执行性能的二进制库文件使用。这个特性目前就已经支持,有了理论的支持,我们就可以着手做改造的事了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值