Flutter 框架初始化与帧循环深度解析
源码路径:packages/flutter/lib/src/widgets/binding.dart
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 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 void runApp(Widget app) { final WidgetsBinding binding = WidgetsFlutterBinding.ensureInitialized(); _runWidget(binding.wrapWithDefaultView(app), binding, 'runApp' ); }void _runWidget(Widget app, WidgetsBinding binding, String debugMethodName) { binding.scheduleAttachRootWidget(app); binding.scheduleWarmUpFrame(); }static WidgetsBinding ensureInitialized() { if (_instance == null ) WidgetsFlutterBinding(); return WidgetsBinding.instance; }
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 @override void initInstances() { super .initInstances(); _instance = this ; buildOwner = BuildOwner(); buildOwner!.onBuildScheduled = _handleBuildScheduled; addPersistentFrameCallback(_drawFrame); }void _handleBuildScheduled() { ensureVisualUpdate(); }
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 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 @override void drawFrame() { try { if (renderViewElement != null ) { buildOwner!.buildScope(renderViewElement!); } super .drawFrame(); } finally { buildOwner!.finalizeTree(); } }
七、帧调度机制 — 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
帧后回调,执行一次后自动移除
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)"]
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() × 7 → scheduleAttachRootWidget() → scheduleWarmUpFrame()
根挂载
attachRootWidget() → RootWidget.attach() → createElement() → buildScope(mount)
每帧循环
Vsync → handleBeginFrame() → handleDrawFrame() → drawFrame() → buildScope + flushLayout + flushPaint
构建调度
setState() → markNeedsBuild() → onBuildScheduled() → ensureVisualUpdate() → 请求 Vsync
帧三阶段
1.buildScope构建 → 2.super.drawFrame()布局+绘制+合成 → 3.finalizeTree清理