Flutter 框架初始化与帧循环深度解析

源码路径:packages/flutter/lib/src/widgets/binding.dart

一、WidgetsFlutterBinding — 七 Mixin 组合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
classDiagram
class WidgetsFlutterBinding {
+ensureInitialized() WidgetsBinding static
}
class BindingBase
class GestureBinding
class SchedulerBinding
class ServicesBinding
class PaintingBinding
class SemanticsBinding
class RendererBinding
class WidgetsBinding

WidgetsFlutterBinding --|> BindingBase
WidgetsFlutterBinding ..|> GestureBinding : with
WidgetsFlutterBinding ..|> SchedulerBinding : with
WidgetsFlutterBinding ..|> ServicesBinding : with
WidgetsFlutterBinding ..|> PaintingBinding : with
WidgetsFlutterBinding ..|> SemanticsBinding : with
WidgetsFlutterBinding ..|> RendererBinding : with
WidgetsFlutterBinding ..|> WidgetsBinding : with
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// L1819: 七 mixin 组合定义
class WidgetsFlutterBinding extends BindingBase
with GestureBinding,
SchedulerBinding,
ServicesBinding,
PaintingBinding,
SemanticsBinding,
RendererBinding,
WidgetsBinding {
static WidgetsBinding ensureInitialized() {
if (_instance == null) WidgetsFlutterBinding();
return WidgetsBinding.instance;
}
}

二、runApp 启动全链路

1
2
3
4
5
6
7
8
9
flowchart TD
A["runApp(app)"] --> B["WidgetsFlutterBinding.ensureInitialized()"]
B --> C["WidgetsFlutterBinding() 构造"]
C --> D["BindingBase() → initInstances × 7"]
D --> E["initServiceExtensions × 7"]
E --> F["_runWidget(binding.wrapWithDefaultView(app))"]
F --> G["scheduleAttachRootWidget(app)"]
G --> H["scheduleWarmUpFrame()"]
H --> I["首帧调度: handleBeginFrame → handleDrawFrame"]

核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// L1574: runApp 入口
void runApp(Widget app) {
final WidgetsBinding binding = WidgetsFlutterBinding.ensureInitialized();
_runWidget(binding.wrapWithDefaultView(app), binding, 'runApp');
}

// L1639: _runWidget
void _runWidget(Widget app, WidgetsBinding binding, String debugMethodName) {
binding.scheduleAttachRootWidget(app);
binding.scheduleWarmUpFrame();
}

// L1840: ensureInitialized
static WidgetsBinding ensureInitialized() {
if (_instance == null) WidgetsFlutterBinding();
return WidgetsBinding.instance;
}

三、WidgetsBinding.initInstances 初始化

1
2
3
4
5
6
7
8
flowchart TD
A["WidgetsBinding.initInstances()"] --> B["super.initInstances()"]
B --> C["_instance = this"]
C --> D["buildOwner = BuildOwner()"]
D --> E["buildOwner.onBuildScheduled = _handleBuildScheduled"]
E --> F["注册栈帧过滤器<br/>ComponentElement/StatefulElement/..."]
F --> G["addPersistentFrameCallback(_drawFrame)"]
G --> H["initServiceExtensions()"]

核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// L537+: WidgetsBinding.initInstances
@override
void initInstances() {
super.initInstances();
_instance = this;
buildOwner = BuildOwner();
buildOwner!.onBuildScheduled = _handleBuildScheduled;
// 注册栈帧过滤器...
addPersistentFrameCallback(_drawFrame); // 每帧回调
}

// L1121: 构建调度
void _handleBuildScheduled() {
ensureVisualUpdate(); // 请求下一帧
}

四、RootWidget.attach — 根挂载

1
2
3
4
5
6
7
flowchart TD
A["RootWidget.attach(owner, element)"] --> B{"element == null?<br/>首次挂载?"}
B -->|是| C["element = createElement() → RootElement"]
C --> D["owner.lockState(assignOwner)"]
D --> E["owner.buildScope(mount)"]
B -->|否| F["element.markNeedsBuild()"]
F --> G["下一帧 rebuild"]

核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// L1696: RootWidget.attach
void attach(BuildOwner owner, Element? element) {
if (element == null) {
owner.lockState(() {
final Element newElement = createElement();
newElement.assignOwner(owner);
owner.buildScope(newElement, () {
newElement.mount(null, null);
});
});
} else {
element.markNeedsBuild();
}
}

五、RootElement 挂载与重建

1
2
3
4
5
6
7
8
9
10
flowchart TD
A["RootElement.mount()"] --> B["super.mount()"]
B --> C["_rebuild()"]
C --> D["updateChild(null, widget.child, null)"]
D --> E["inflateWidget → createElement → mount"]

F["RootElement.performRebuild()"] --> G{"_newWidget != null?"}
G -->|有延迟更新| H["_child = updateChild(_child, _newWidget, ...)"]
G -->|无| I["_rebuild()"]
H --> J["_newWidget = null"]

六、drawFrame — 帧循环核心

drawFrame 是每帧执行的核心回调,通过 addPersistentFrameCallback 注册到 SchedulerBinding。

1
2
3
4
5
6
7
8
9
10
11
12
flowchart TD
A["drawFrame()"] --> B["buildOwner!.buildScope(rootElement!)"]
B --> C["构建 dirty Elements"]
C --> D["super.drawFrame()"]
D --> D1["RendererBinding.drawFrame()"]
D1 --> D2["pipelineOwner.flushLayout()"]
D2 --> D3["pipelineOwner.flushCompositingBits()"]
D3 --> D4["pipelineOwner.flushPaint()"]
D4 --> D5["pipelineOwner.flushSemantics()"]
D5 --> D6["renderView.compositeFrame()"]
D6 --> E["buildOwner!.finalizeTree()"]
E --> F["unmount 不可恢复的 inactive Elements"]

核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// L1227: WidgetsBinding.drawFrame
@override
void drawFrame() {
// ... 省略调试逻辑
try {
if (renderViewElement != null) {
buildOwner!.buildScope(renderViewElement!); // 1. 构建
}
super.drawFrame(); // 2. 布局+绘制+合成
// super.drawFrame() 调用链:
// RendererBinding.drawFrame()
// → pipelineOwner.flushLayout()
// → pipelineOwner.flushCompositingBits()
// → pipelineOwner.flushPaint()
// → renderView.compositeFrame()
} finally {
buildOwner!.finalizeTree(); // 3. 清理
}
}

七、帧调度机制 — SchedulerBinding

1
2
3
4
5
6
7
flowchart TD
A["Vsync 信号"] --> B["handleBeginFrame(rawTimeStamp)"]
B --> C["处理 transientCallbacks (_transientCallbacks)"]
C --> D["handleDrawFrame()"]
D --> E["处理 persistentCallbacks (_persistentCallbacks)"]
E --> F["drawFrame() — 帧循环核心"]
F --> G["处理 postFrameCallbacks (_postFrameCallbacks)"]

帧回调类型

回调类型 注册方法 用途
transientCallback addTransientFrameCallback 一次性动画回调,帧后自动移除
persistentCallback addPersistentFrameCallback 持久回调,每帧执行(如 drawFrame)
postFrameCallback addPostFrameCallback 帧后回调,执行一次后自动移除

八、scheduleAttachRootWidget — 异步根挂载

1
2
3
4
5
6
7
8
flowchart TD
A["scheduleAttachRootWidget(rootWidget)"] --> B{"_rootElement != null?"}
B -->|是| C["_rootElement.widget.child = rootWidget<br/>markNeedsBuild()"]
B -->|否| D["attachRootWidget(rootWidget)"]
D --> E["attachToBuildOwner(RootWidget(child: rootWidget))"]
E --> F["RootWidget.attach(owner, null)"]
F --> G["createElement() → RootElement"]
G --> H["assignOwner → buildScope(mount)"]

九、WidgetsBindingObserver 观察者接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classDiagram
class WidgetsBindingObserver {
<<interface>>
+didPopRoute() bool
+didPushRoute(route) bool
+didPushRouteInformation(info) bool
+didChangeAppLifecycleState(state)
+didChangeMetrics()
+didChangeTextScaleFactor()
+didChangePlatformBrightness()
+didChangeLocales()
+didChangeAccessibilityFeatures()
+handleStartBackGesture() bool
+handleUpdateBackGesture(progress) bool
+handleCommitBackGesture() bool
}

注册/注销观察者:

1
2
3
4
// 注册
WidgetsBinding.instance.addObserver(observer);
// 注销
WidgetsBinding.instance.removeObserver(observer);

十、从 runApp 到首帧渲染完整流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
flowchart TD
A["runApp(MyApp)"] --> B["WidgetsFlutterBinding.ensureInitialized()"]
B --> C["BindingBase 构造"]
C --> D["7个 Binding 的 initInstances"]
D --> E["7个 Binding 的 initServiceExtensions"]
E --> F["scheduleAttachRootWidget(wrapWithDefaultView(MyApp))"]
F --> G["scheduleWarmUpFrame()"]
G --> H["handleBeginFrame()"]
H --> I["handleDrawFrame()"]
I --> J["drawFrame()"]
J --> K["buildScope → RootElement.mount → _rebuild"]
K --> L["Widget Tree 构建 → Element Tree 构建"]
L --> M["RenderObjectElement.mount → createRenderObject"]
M --> N["flushLayout → flushCompositingBits → flushPaint"]
N --> O["首帧渲染完成"]

十一、关键调用链总结

场景 调用链
应用启动 runApp()ensureInitialized()initInstances() × 7scheduleAttachRootWidget()scheduleWarmUpFrame()
根挂载 attachRootWidget()RootWidget.attach()createElement()buildScope(mount)
每帧循环 VsynchandleBeginFrame()handleDrawFrame()drawFrame()buildScope + flushLayout + flushPaint
构建调度 setState()markNeedsBuild()onBuildScheduled()ensureVisualUpdate() → 请求 Vsync
帧三阶段 1.buildScope构建 → 2.super.drawFrame()布局+绘制+合成 → 3.finalizeTree清理