控制加载顺序,优化性能与内存
本页面描述了展示一个 Flutter UI 的分解步骤。知道了这一点,你可以就何时对 Flutter 引擎进行预热,在哪个阶段可以进行哪些操作,以及这些操作的潜在问题和内存成本做出更好、更明智的决策。
加载 Flutter
#在展示 Flutter UI 时, Android 与 iOS 应用(用于集成到现有应用的两个受支持的平台),纯 Flutter 应用,以及 add-to-app 的模式,在概念上的加载步骤顺序相似。
查找 Flutter 资源
#Flutter 的引擎运行时和应用已编译的 Dart 代码都被打包为 Android 和 iOS 上的共享库。加载 Flutter 的第一步是在 .apk、.ipa 或 .app 中查找这些资源(以及其他 Flutter 资源,例如图像和字体,假如适用的话还有 JIT 代码)。
当你首次在 Android 和 iOS
上调用 API 构建 FlutterEngine
时,就会发生这种情况。
加载 Flutter 库
#找到后,引擎的共享库将在每个进程中加载一次内存。
在 Android 上,当构建
FlutterEngine
时也会发生这种情况,因为 JNI 连接器需要引用 Flutter C++ 库。在 iOS 上,这是在首次运行
FlutterEngine
时发生的,例如运行 runWithEntrypoint:
。
启动 Dart VM
#Dart 运行时负责管理 Dart 代码的 Dart 内存与异步。在 JIT 模式下,它还负责在运行时将 Dart 源代码编译为机器码。
在 Android 和 iOS 上,每个应用程序会话都存在一个 Dart 运行时。
在 Android 上首次构建
FlutterEngine
,以及在 iOS 上首次
运行 Dart 入口
时,将完成一次 Dart VM 启动。
此时,你的 Dart 代码的 snapshot 也将从应用程序的文件加载到内存中。
即使你直接使用 Dart SDK而没 Flutter 引擎,也会这样执行,这是一个通用的过程。
Dart VM 启动后永远不会关闭。
创建并运行一个 Dart Isolate
#在初始化 Dart 运行时之后,下一步就是 Flutter 引擎对 Dart 运行时的使用。
这是通过在 Dart 运行时中启动
Dart Isolate
来完成的。
isolate 是 Dart 的内存和线程容器。此时在宿主平台上还创建了许多
辅助线程 来支持 isolate,例如用于解除 GPU 处理的线程和用于图像解码的线程。
每个 FlutterEngine
实例都存在一个 isolate,并且同一个 Dart VM 可以承载多个 isolate。
在 Android 上,当你在 FlutterEngine
实例上调用
DartExecutor.executeDartEntrypoint()
时,就会发生这种情况。
在 iOS 上,当你对 FlutterEngine
实例调用 runWithEntrypoint:
时会发生这种情况。
此时,Dart 代码会执行默认的入口点方法 (默认是 main.dart
文件的 main()
方法) ,如果你在 main()
方法中调用 Flutter 的 runApp()
方法,则你的 Flutter 应用或库的 widget 树将会创建并构建。如果你需要阻止某些功能在 Flutter 代码中执行,则需要使用枚举值 AppLifecycleState.detached
表示其不绑定在任何 UI 组件上。
将 UI 挂载到 Flutter 引擎
#启动后不久,一个标准的完整的 Flutter 应用程序便会达到此状态。
在 add-to-app 的场景中,例如通过在 Android 上使用 FlutterActivity.withCachedEngine()
方法构建的 Intent
,调用 startActivity()
时,或者,在 iOS 上调用 initWithEngine: nibName: bundle:
,展示实例化的 FlutterViewController
,都会将 FlutterEngine
挂载到 UI 组件。
如果在没有启动 Flutter UI 组件的情况下也是如此,
例如在 Android 上使用 FlutterActivity.createDefaultIntent()
或在 iOS 上使用 FlutterViewController initWithProject: nibName: bundle:
预热一个 FlutterEngine
。在这些情况下,将创建一个隐式的 FlutterEngine
。
在后台,这两个平台的UI组件都为 FlutterEngine
提供了渲染层,例如 Android 上的 Surface
或 iOS 上的 CAEAGLLayer
或 CAMetalLayer。
此时,你的 Flutter 程序生成的 Layer
树将转换为 OpenGL(或 Vulkan 或 Metal)GPU 指令。
除非另有说明,本文档之所提及适用于 Flutter 的最新稳定版本,本页面最后更新时间: 2025-10-09。 查看文档源码 或者 为本页面内容提出建议.