启动流程分析

Catalogue   

需要的前置知识:

核心类和函数

PlatformDispatcher

平台事件转发器,单例对象。比如每一帧的渲染回调、系统语言切换等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/// 单例对象
static PlatformDispatcher get instance => _instance;
static final PlatformDispatcher _instance = PlatformDispatcher._();

/// 配置信息(是否使用24小时制、文本缩放大小、语言、主题等) 发生变化时回调onPlatformConfigurationChanged
PlatformConfiguration get configuration => _configuration;
PlatformConfiguration _configuration = const PlatformConfiguration();

/// 当前视图列表,当它们发生变化时,回调onMetricsChanged
/// FlutterView对UI进行了封装
Iterable<FlutterView> get views => _views.values;
Map<Object, FlutterView> _views = <Object, FlutterView>{};

/// 新的一帧开启时回调
FrameCallback? get onBeginFrame => _onBeginFrame;
FrameCallback? _onBeginFrame;

/// onBeginFrame完成后执行该回调
VoidCallback? get onDrawFrame => _onDrawFrame;
VoidCallback? _onDrawFrame;

/// 手势交互回调,GestureBinding处理
PointerDataPacketCallback? get onPointerDataPacket => _onPointerDataPacket;
PointerDataPacketCallback? _onPointerDataPacket;

/// 平台消息回调
PlatformMessageCallback? get onPlatformMessage => _onPlatformMessage;
PlatformMessageCallback? _onPlatformMessage;

/// 执行后,onBeginFrame、onDrawFrame会执行,参考SchedulerBinding
void scheduleFrame() native 'PlatformConfiguration_scheduleFrame';

/// 语言切换回调
VoidCallback? get onLocaleChanged => _onLocaleChanged;
VoidCallback? _onLocaleChanged;

FlutterView

FlutterView对象window是对PlatformDispatcher的封装,是与平台层的交互入口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/// 要被绘制的UI对象
abstract class FlutterView {
/// 持有平台消息分发器
PlatformDispatcher get platformDispatcher;

/// 被系统挡住的屏幕物理像素,比如软键盘弹起,则EdgeInsets的bottom会大于0
WindowPadding get viewInsets => viewConfiguration.viewInsets;

/// 被系统UI挡住的屏幕物理像素,比如系统通知栏,iphone的底部功能键
WindowPadding get viewPadding => viewConfiguration.viewPadding;

/// max(0.0, FlutterView.viewPadding - FlutterView.viewInsets)
WindowPadding get padding => viewConfiguration.padding;

/// 屏幕像素密度,物理像素和虚拟像素的比值
double get devicePixelRatio => viewConfiguration.devicePixelRatio;

/// 通知底层进行渲染
void render(Scene scene) => _render(scene, this);
void _render(Scene scene, FlutterView view) native 'PlatformConfiguration_render';
}

class FlutterWindow extends FlutterView {}

class SingletonFlutterWindow extends FlutterWindow {

/// 对platformDispatcher中的回调方法进行了一层封装

VoidCallback? get onMetricsChanged => platformDispatcher.onMetricsChanged;
set onMetricsChanged(VoidCallback? callback) {
platformDispatcher.onMetricsChanged = callback;
}

VoidCallback? get onLocaleChanged => platformDispatcher.onLocaleChanged;
set onLocaleChanged(VoidCallback? callback) {
platformDispatcher.onLocaleChanged = callback;
}
VoidCallback? get onLocaleChanged => platformDispatcher.onLocaleChanged;
set onLocaleChanged(VoidCallback? callback) {
platformDispatcher.onLocaleChanged = callback;
}
VoidCallback? get onLocaleChanged => platformDispatcher.onLocaleChanged;
set onLocaleChanged(VoidCallback? callback) {
platformDispatcher.onLocaleChanged = callback;
}
VoidCallback? get onLocaleChanged => platformDispatcher.onLocaleChanged;
set onLocaleChanged(VoidCallback? callback) {
platformDispatcher.onLocaleChanged = callback;
}
VoidCallback? get onLocaleChanged => platformDispatcher.onLocaleChanged;
set onLocaleChanged(VoidCallback? callback) {
platformDispatcher.onLocaleChanged = callback;
}
VoidCallback? get onLocaleChanged => platformDispatcher.onLocaleChanged;
set onLocaleChanged(VoidCallback? callback) {
platformDispatcher.onLocaleChanged = callback;
}
VoidCallback? get onLocaleChanged => platformDispatcher.onLocaleChanged;
set onLocaleChanged(VoidCallback? callback) {
platformDispatcher.onLocaleChanged = callback;
}
}

入口函数及相关类

main入口调用runApp函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
void runApp(Widget app) {
WidgetsFlutterBinding.ensureInitialized()//初始化操作
..scheduleAttachRootWidget(app)//将传入的Widget包装进RenderObjectToWidgetAdapter
..scheduleWarmUpFrame();//SchedulerBinding进行绘制
}

class WidgetsFlutterBinding extends BindingBase with GestureBinding, SchedulerBinding, ServicesBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding {
static WidgetsBinding ensureInitialized() {
if (WidgetsBinding.instance == null)
WidgetsFlutterBinding();
return WidgetsBinding.instance!;
}
}
  • BindingBase:绑定的基类
  • WidgetsBinding:绑定组件树,提供onLocalChanged、onBuildScheduled等回调
  • RendererBinding:绑定渲染树,提供window.onMetricsChanged、window.onTextScaleDactorChanged等回调
  • SemanticsBinding(绑定语义树)
  • PaintingBinding(图片缓存操作)
  • ServicesBinding:绑定平台服务消息,注册Dart层和C++层的消息传输服务,提供window.onPlatformMessage回调
  • SchedulerBinding:绑定帧绘制回调函数,以及widget生命周期相关事件,提供window.onBeginFrame和window.onDrawFrame回调
  • GestureBinding:绑定手势事件,用于检测应用的各种手势相关操作,提供window.onPointerDataPacket回调

BindingBase

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
abstract class BindingBase {


/// 绑定的主视图
ui.SingletonFlutterWindow get window => ui.window;
/// 持有平台事件分发器
ui.PlatformDispatcher get platformDispatcher => ui.PlatformDispatcher.instance;

/// 混入的方式初始化不同的Binding对象
void initInstances() {
assert(!_debugInitialized);
assert(() {
_debugInitialized = true;
return true;
}());
}
}


RenderBinding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureBinding, SemanticsBinding, HitTestable {
@override
void initInstances() {
super.initInstances();
_instance = this;
// 管理RenderObject对象
_pipelineOwner = PipelineOwner(
onNeedVisualUpdate: ensureVisualUpdate,
onSemanticsOwnerCreated: _handleSemanticsOwnerCreated,
onSemanticsOwnerDisposed: _handleSemanticsOwnerDisposed,
);
// 监听平台事件的回调
window
..onMetricsChanged = handleMetricsChanged
..onTextScaleFactorChanged = handleTextScaleFactorChanged
..onPlatformBrightnessChanged = handlePlatformBrightnessChanged
..onSemanticsEnabledChanged = _handleSemanticsEnabledChanged
..onSemanticsAction = _handleSemanticsAction;
// 生成RenderView作为根节点,RenderView继承自RenderObject
initRenderView();
_handleSemanticsEnabledChanged();
assert(renderView != null);
// 监听帧刷新回调,Flutter侧进行布局、绘制
addPersistentFrameCallback(_handlePersistentFrameCallback);
// 手势处理
initMouseTracker();
if (kIsWeb) {
addPostFrameCallback(_handleWebFirstFrame);
}
}


void drawFrame() {
assert(renderView != null);
pipelineOwner.flushLayout();//布局
pipelineOwner.flushCompositingBits();//
pipelineOwner.flushPaint();//绘制
if (sendFramesToEngine) {
renderView.compositeFrame(); // this sends the bits to the GPU
pipelineOwner.flushSemantics(); // this also sends the semantics to the OS.
_firstFrameSent = true;
}
}

/// 事件传递
@override // from GestureBinding
void dispatchEvent(PointerEvent event, HitTestResult? hitTestResult) {
_mouseTracker!.updateWithEvent(
event,
// Enter and exit events should be triggered with or without buttons
// pressed. When the button is pressed, normal hit test uses a cached
// result, but MouseTracker requires that the hit test is re-executed to
// update the hovering events.
() => (hitTestResult == null || event is PointerMoveEvent) ? renderView.hitTestMouseTrackers(event.position) : hitTestResult,
);
super.dispatchEvent(event, hitTestResult);
}

}

PaintingBinding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

mixin PaintingBinding on BindingBase, ServicesBinding {

@override
void initInstances() {
super.initInstances();
_instance = this;
_imageCache = createImageCache();//图片缓存,1000张图片,最大内存100MiB
shaderWarmUp?.execute();//异步方法,初始化了一个默认的着色器,避免需要着色器的时候再初始化出现掉帧现象。
}

/// 内存警告回调,清理图片缓存
@override
void handleMemoryPressure() {
super.handleMemoryPressure();
imageCache?.clear();
}

}

ServiceBinding

主要用来接收MethodChannel和SystemChannels传递过来的消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

mixin ServicesBinding on BindingBase, SchedulerBinding {


/// 跟平台通信的消息管理器
BinaryMessenger get defaultBinaryMessenger => _defaultBinaryMessenger;
late final BinaryMessenger _defaultBinaryMessenger;

@override
void initInstances() {
super.initInstances();
_instance = this;
// 创建MethodChannel
_defaultBinaryMessenger = createBinaryMessenger();
// RestorationManager用于恢复界面数据的功能
_restorationManager = createRestorationManager();
// 初始化键盘
_initKeyboard();
initLicenses();
//系统消息回调监听
SystemChannels.system.setMessageHandler((dynamic message) => handleSystemMessage(message as Object));
SystemChannels.lifecycle.setMessageHandler(_handleLifecycleMessage);
SystemChannels.platform.setMethodCallHandler(_handlePlatformMessage);
// 读取当前的生命周期状态,处理则是在SchedulerBinding这个mixin中。
readInitialLifecycleStateFromNativeWindow();
}

}


SchedulerBinding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

/// 调度阶段 绘制调度、task调度
enum SchedulerPhase {
idle,// 处理task、microtask、timer回调,用户输入和手势等
transientCallbacks,//处理动画状态的计算和更新
midFrameMicrotasks,//处理transientCallbacks阶段触发的microtasks
persistentCallbacks,//处理build、layout、paint
postFrameCallbacks,//当前阶段结束时的清理工作
}

///
mixin SchedulerBinding on BindingBase {

/// 永久callback,一经添加无法移除,由WidgetsBinding.instance.addPersitentFrameCallback()注册,这个回调处理了布局与绘制工作。
final List<FrameCallback> _persistentCallbacks = <FrameCallback>[];

/// 只会调用一次,调用后会被系统移除,可由WidgetsBinding.instance.addPostFrameCallback()注册,该回调一般用于State的更新。
final List<FrameCallback> _postFrameCallbacks = <FrameCallback>[];

/// 通过Ticker的scheduleTick添加回调,一般用于动画的回调
Map<int, _FrameCallbackEntry> _transientCallbacks = <int, _FrameCallbackEntry>{};


/// 应用生命周期发生变化时回调
/// 可以使用WidgetsBindingObserver.didChangeAppLifecycleState监听来实现自己的业务逻辑
void handleAppLifecycleStateChanged(AppLifecycleState state) {
assert(state != null);
_lifecycleState = state;
switch (state) {
case AppLifecycleState.resumed:
case AppLifecycleState.inactive:
_setFramesEnabledState(true);
break;
case AppLifecycleState.paused:
case AppLifecycleState.detached:
_setFramesEnabledState(false);//停止刷新界面
break;
}
}

bool _framesEnabled = true;
void _setFramesEnabledState(bool enabled) {
if (_framesEnabled == enabled)
return;
_framesEnabled = enabled;
if (enabled)
scheduleFrame();
}

void scheduleFrame() {
if (_hasScheduledFrame || !framesEnabled)
return;
assert(() {
if (debugPrintScheduleFrameStacks)
debugPrintStack(label: 'scheduleFrame() called. Current phase is $schedulerPhase.');
return true;
}());
//确保向window注册了onBeginFrame和onDrawFrame
ensureFrameCallbacksRegistered();
// 向平台层发送刷新请求,进行下一轮帧刷新
window.scheduleFrame();
_hasScheduledFrame = true;
}

@protected
void ensureFrameCallbacksRegistered() {
window.onBeginFrame ??= _handleBeginFrame;
window.onDrawFrame ??= _handleDrawFrame;
}

void handleBeginFrame(Duration? rawTimeStamp) {
_frameTimelineTask?.start('Frame', arguments: timelineArgumentsIndicatingLandmarkEvent);
_firstRawTimeStampInEpoch ??= rawTimeStamp;
_currentFrameTimeStamp = _adjustForEpoch(rawTimeStamp ?? _lastRawTimeStamp);
if (rawTimeStamp != null)
_lastRawTimeStamp = rawTimeStamp;

assert(schedulerPhase == SchedulerPhase.idle);
_hasScheduledFrame = false;
try {
// TRANSIENT FRAME CALLBACKS
_frameTimelineTask?.start('Animate', arguments: timelineArgumentsIndicatingLandmarkEvent);
_schedulerPhase = SchedulerPhase.transientCallbacks;
final Map<int, _FrameCallbackEntry> callbacks = _transientCallbacks;
_transientCallbacks = <int, _FrameCallbackEntry>{};
callbacks.forEach((int id, _FrameCallbackEntry callbackEntry) {
if (!_removedIds.contains(id))
_invokeFrameCallback(callbackEntry.callback, _currentFrameTimeStamp!, callbackEntry.debugStack);
});
_removedIds.clear();
} finally {
_schedulerPhase = SchedulerPhase.midFrameMicrotasks;
}
}

void handleDrawFrame() {
assert(_schedulerPhase == SchedulerPhase.midFrameMicrotasks);
_frameTimelineTask?.finish(); // end the "Animate" phase
try {
// PERSISTENT FRAME CALLBACKS
_schedulerPhase = SchedulerPhase.persistentCallbacks;
for (final FrameCallback callback in _persistentCallbacks)
_invokeFrameCallback(callback, _currentFrameTimeStamp!);

// POST-FRAME CALLBACKS
_schedulerPhase = SchedulerPhase.postFrameCallbacks;
final List<FrameCallback> localPostFrameCallbacks =
List<FrameCallback>.of(_postFrameCallbacks);
_postFrameCallbacks.clear();
for (final FrameCallback callback in localPostFrameCallbacks)
_invokeFrameCallback(callback, _currentFrameTimeStamp!);
} finally {
_schedulerPhase = SchedulerPhase.idle;
_frameTimelineTask?.finish(); // end the Frame
assert(() {
if (debugPrintEndFrameBanner)
debugPrint('▀' * _debugBanner!.length);
_debugBanner = null;
return true;
}());
_currentFrameTimeStamp = null;
}
}


/// Frame即每一帧的绘制过程,engine通过VSync信号不断地触发Frame的绘制,实际上就是调用SchedulerBinding类中的_handleBeginFrame()和_handleDrawFrame()这两个方法,这个过程中会完成动画、布局、绘制等工作。
void scheduleWarmUpFrame() {
if (_warmUpFrame || schedulerPhase != SchedulerPhase.idle)
return;

_warmUpFrame = true;
final TimelineTask timelineTask = TimelineTask()..start('Warm-up frame');
final bool hadScheduledFrame = _hasScheduledFrame;
// We use timers here to ensure that microtasks flush in between.
Timer.run(() {
assert(_warmUpFrame);
handleBeginFrame(null);
});
Timer.run(() {
assert(_warmUpFrame);
handleDrawFrame();
resetEpoch();
_warmUpFrame = false;
if (hadScheduledFrame)
scheduleFrame();
});

lockEvents(() async {
await endOfFrame;
timelineTask.finish();
});
}


}

GestureBinding

处理用户的交互

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

mixin GestureBinding on BindingBase implements HitTestable, HitTestDispatcher, HitTestTarget {

@override
void initInstances() {
super.initInstances();
_instance = this;
window.onPointerDataPacket = _handlePointerDataPacket;
}

void _handlePointerDataPacket(ui.PointerDataPacket packet) {
// We convert pointer data to logical pixels so that e.g. the touch slop can be
// defined in a device-independent manner.
_pendingPointerEvents.addAll(PointerEventConverter.expand(packet.data, window.devicePixelRatio));
if (!locked)
_flushPointerEventQueue();
}

void _flushPointerEventQueue() {
assert(!locked);

while (_pendingPointerEvents.isNotEmpty)
handlePointerEvent(_pendingPointerEvents.removeFirst());
}

void handlePointerEvent(PointerEvent event) {
assert(!locked);

if (resamplingEnabled) {
_resampler.addOrDispatch(event);
_resampler.sample(samplingOffset, _samplingClock);
return;
}

// Stop resampler if resampling is not enabled. This is a no-op if
// resampling was never enabled.
_resampler.stop();
_handlePointerEventImmediately(event);
}

void _handlePointerEventImmediately(PointerEvent event) {
HitTestResult? hitTestResult;
if (event is PointerDownEvent || event is PointerSignalEvent || event is PointerHoverEvent) {
assert(!_hitTests.containsKey(event.pointer));
hitTestResult = HitTestResult();//记录事件传递所经过的节点
hitTest(hitTestResult, event.position);
if (event is PointerDownEvent) {
_hitTests[event.pointer] = hitTestResult;
}
assert(() {
if (debugPrintHitTestResults)
debugPrint('$event: $hitTestResult');
return true;
}());
} else if (event is PointerUpEvent || event is PointerCancelEvent) {
hitTestResult = _hitTests.remove(event.pointer);
} else if (event.down) {
hitTestResult = _hitTests[event.pointer];
}
assert(() {
if (debugPrintMouseHoverEvents && event is PointerHoverEvent)
debugPrint('$event');
return true;
}());
if (hitTestResult != null ||
event is PointerAddedEvent ||
event is PointerRemovedEvent) {
assert(event.position != null);
dispatchEvent(event, hitTestResult);
}
}

@override // from HitTestable
void hitTest(HitTestResult result, Offset position) {
result.add(HitTestEntry(this));
}

/// 事件分发流程
/// 先调用RenderBinding中的dispatchEvent,遍历renderView的所有widget,将hitTestResult返回
void dispatchEvent(PointerEvent event, HitTestResult? hitTestResult) {
assert(!locked);
if (hitTestResult == null) {
assert(event is PointerAddedEvent || event is PointerRemovedEvent);
try {
pointerRouter.route(event);
} catch (exception, stack) {
}
return;
}
for (final HitTestEntry entry in hitTestResult.path) {
try {
entry.target.handleEvent(event.transformed(entry.transform), entry);
} catch (exception, stack) {
}
}
}

/// 手势竞技场进行处理
@override // from HitTestTarget
void handleEvent(PointerEvent event, HitTestEntry entry) {
pointerRouter.route(event);
if (event is PointerDownEvent) {
gestureArena.close(event.pointer);
} else if (event is PointerUpEvent) {
gestureArena.sweep(event.pointer);
} else if (event is PointerSignalEvent) {
pointerSignalResolver.resolve(event);
}
}
}

WidgetsBinding

处理widget树的逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34


mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureBinding, RendererBinding, SemanticsBinding {

/// 光标管理器
FocusManager get focusManager => _buildOwner!.focusManager;

/// 应用生命周期回调,回到App、回到桌面、内存不足、语言切换、主题切换、文字大小切换等
final List<WidgetsBindingObserver> _observers = <WidgetsBindingObserver>[];

@override
void initInstances() {
super.initInstances();
_instance = this;

assert(() {
_debugAddStackFilters();
return true;
}());

// Initialization of [_buildOwner] has to be done after
// [super.initInstances] is called, as it requires [ServicesBinding] to
// properly setup the [defaultBinaryMessenger] instance.
// 初始化BuildOwner,用来执行widget树的build任务
_buildOwner = BuildOwner();
buildOwner!.onBuildScheduled = _handleBuildScheduled;
//语言切换回调
window.onLocaleChanged = handleLocaleChanged;
window.onAccessibilityFeaturesChanged = handleAccessibilityFeaturesChanged;
SystemChannels.navigation.setMethodCallHandler(_handleNavigationInvocation);//系统路由监听?
}

}

scheduleAttachRootWidget

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186


void scheduleAttachRootWidget(Widget rootWidget) {
Timer.run(() {
attachRootWidget(rootWidget);
});
}

void attachRootWidget(Widget rootWidget) {
final bool isBootstrapFrame = renderViewElement == null;
_readyToProduceFrames = true;
_renderViewElement = RenderObjectToWidgetAdapter<RenderBox>(
container: renderView,//RenderBinding构建的根节点
debugShortDescription: '[root]',
child: rootWidget,//rootWidget是我们自己的AppWidget
).attachToRenderTree(buildOwner!, renderViewElement as RenderObjectToWidgetElement<RenderBox>?);
if (isBootstrapFrame) {
SchedulerBinding.instance!.ensureVisualUpdate();
}
}



class RenderObjectToWidgetAdapter<T extends RenderObject> extends RenderObjectWidget {
RenderObjectToWidgetElement<T> attachToRenderTree(BuildOwner owner, [ RenderObjectToWidgetElement<T>? element ]) {
if (element == null) {
owner.lockState(() {
element = createElement();//创建RenderObjectElement的子类RenderObjectToWidgetElement
assert(element != null);
element!.assignOwner(owner);
});
//BuildOwner
owner.buildScope(element!, () {
element!.mount(null, null);
});
} else {
element._newWidget = this;
element.markNeedsBuild();
}
return element!;
}
}


class RenderObjectToWidgetElement<T extends RenderObject> extends RootRenderObjectElement {
void mount(Element? parent, Object? newSlot) {
assert(parent == null);
super.mount(parent, newSlot);
_rebuild();
assert(_child != null);
}

void _rebuild() {
try {
_child = updateChild(_child, widget.child, _rootChildSlot);
} catch (exception, stack) {
final FlutterErrorDetails details = FlutterErrorDetails(
exception: exception,
stack: stack,
library: 'widgets library',
context: ErrorDescription('attaching to the render tree'),
);
FlutterError.reportError(details);
final Widget error = ErrorWidget.builder(details);
_child = updateChild(null, error, _rootChildSlot);
}
}

Element? updateChild(Element? child, Widget? newWidget, Object? newSlot) {
if (newWidget == null) {
if (child != null)
deactivateChild(child);//新widget为空,旧的存在,则需要销毁
return null;
}

final Element newChild;
if (child != null) {
bool hasSameSuperclass = true;
if (hasSameSuperclass && child.widget == newWidget) {
if (child.slot != newSlot)
updateSlotForChild(child, newSlot);
newChild = child;
} else if (hasSameSuperclass && Widget.canUpdate(child.widget, newWidget)) {
if (child.slot != newSlot)
updateSlotForChild(child, newSlot);
if (!kReleaseMode && debugProfileBuildsEnabled) {
Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent;
Timeline.startSync(
'${newWidget.runtimeType}',
arguments: debugTimelineArguments,
);
}
child.update(newWidget);
if (!kReleaseMode && debugProfileBuildsEnabled)
Timeline.finishSync();
newChild = child;
} else {
deactivateChild(child);
assert(child._parent == null);
if (!kReleaseMode && debugProfileBuildsEnabled) {
Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent;
Timeline.startSync(
'${newWidget.runtimeType}',
arguments: debugTimelineArguments,
);
}
newChild = inflateWidget(newWidget, newSlot);
if (!kReleaseMode && debugProfileBuildsEnabled)
Timeline.finishSync();
}
} else {
if (!kReleaseMode && debugProfileBuildsEnabled) {
Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent;
Timeline.startSync(
'${newWidget.runtimeType}',
arguments: debugTimelineArguments,
);
}
newChild = inflateWidget(newWidget, newSlot);//child为null,则需要填充新视图
if (!kReleaseMode && debugProfileBuildsEnabled)
Timeline.finishSync();
}

return newChild;
}

Element inflateWidget(Widget newWidget, Object? newSlot) {
final Key? key = newWidget.key;
if (key is GlobalKey) {
final Element? newChild = _retakeInactiveElement(key, newWidget);
if (newChild != null) {
newChild._activateWithParent(this, newSlot);
final Element? updatedChild = updateChild(newChild, newWidget, newSlot);
assert(newChild == updatedChild);
return updatedChild!;
}
}
final Element newChild = newWidget.createElement();//创建新的Element
newChild.mount(this, newSlot);//递归mount
return newChild;
}

}


abstract class RenderObjectElement extends Element {
@override
void mount(Element? parent, Object? newSlot) {
super.mount(parent, newSlot);
assert(() {
_debugDoingBuild = true;
return true;
}());
_renderObject = widget.createRenderObject(this);
attachRenderObject(newSlot);//挂载到RenderObject树
_dirty = false;
}
}

abstract class Element extends DiagnosticableTree implements BuildContext {
void mount(Element? parent, Object? newSlot) {
assert(_lifecycleState == _ElementLifecycle.initial);
assert(widget != null);
assert(_parent == null);
assert(parent == null || parent._lifecycleState == _ElementLifecycle.active);
assert(slot == null);
_parent = parent;//Element树当前节点的父节点
_slot = newSlot;//插槽
_lifecycleState = _ElementLifecycle.active;
_depth = _parent != null ? _parent!.depth + 1 : 1;//节点深度
if (parent != null) {
// Only assign ownership if the parent is non-null. If parent is null
// (the root node), the owner should have already been assigned.
// See RootRenderObjectElement.assignOwner().
_owner = parent.owner;
}
assert(owner != null);
final Key? key = widget.key;
if (key is GlobalKey) {
owner!._registerGlobalKey(key, this);
}
_updateInheritance();
}
}


scheduleWarmUpFrame

ScheduleBinding中调用handleBeginFrame和handleDrawFrame绘制一帧并传递给GPU去渲染。

总结

  1. runApp启动程序;
  2. WidgetFlutterBinding初始化;WidgetsFlutterBinding混入了GestureBinding, SchedulerBinding, ServicesBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding。
    2.1. WidgetsBinding中创建BuildOwner,其用于处理widget树的build任务;
    2.2. RendererBinding创建PipelineOwner,其用于管理RenderObject对象;
  3. 用FlutterView将runApp的参数包裹起来,里面还包裹了_MediaQueryFromView,其可以返回MediaQueryData来获取屏幕的大小等值;
  4. scheduleAttachRootWidget调用attachRootWidget,创建Widget Tree的根节点RenderObjectToWidgetAdapter,它的createElement创建Element Tree的根节点(RenderObjectToWidgetElement),createRenderObject返回的是PipelineOwner中的rootNode;
  5. BuildOwner调用buildScope执行build流程,mount的时候调用createRenderObject构建Render Tree;
  6. scheduleWarmUpFrame尽可能触发一次帧渲染

参考