1. 简介
让我们从 main开始,一步一步查看一下runApp 到底经历了什么
import 'package:flutter/material.dart';
void main() {
runApp(const MyAPP2());
}
class MyAPP2 extends StatelessWidget {
const MyAPP2({super.key});
@override
Widget build(BuildContext context) {
return Padding(padding: EdgeInsets.all(0));
}
@override
StatelessElement createElement() {
// return super.createElement();
var element = MyApp2Element(this);
return element;
}
}
class MyApp2Element extends StatelessElement {
MyApp2Element(super.widget);
@override
void mount(Element? parent, Object? newSlot) {
super.mount(parent, newSlot);
}
}
2. runApp(const MyAPP2())
void runApp(Widget app) {
// 1.获取一个 WidgetsFlutterBinding 的单例
WidgetsFlutterBinding.ensureInitialized()
// 2.
..scheduleAttachRootWidget(app)
// 3. 初始化帧
..scheduleWarmUpFrame();
}
2.1 往下我们看看 scheduleAttachRootWidget
@protected
void scheduleAttachRootWidget(Widget rootWidget) {
// 主要是添加一个任务
Timer.run(() {
attachRootWidget(rootWidget);
});
}
2.2 进入 attachRootWidget(rootWidget);
void attachRootWidget(Widget rootWidget) {
final bool isBootstrapFrame = renderViewElement == null;
_readyToProduceFrames = true;
// 2.2.1 RenderObjectToWidgetAdapter
_renderViewElement = RenderObjectToWidgetAdapter<RenderBox>(
// 2.2.2 初始化 WidgetsFlutterBinding => BindingBase => initInstances() => RenderBinding.initInstances() =>
// renderView = RenderView(configuration: createViewConfiguration(), window: window); 拿到renderView
container: renderView,
debugShortDescription: '[root]',
// 这个Widget 就是我们的MyApp2
child: rootWidget,
)
// _buildOwner = BuildOwner();
.attachToRenderTree(buildOwner!, renderViewElement as RenderObjectToWidgetElement<RenderBox>?);
if (isBootstrapFrame) {
SchedulerBinding.instance.ensureVisualUpdate();
}
}
3. 接下来我们去分析一下 element.mount
进入 RenderObjectToWidgetElement
3.1 先看看 RenderObjectToWidgetElement的 mount 和 super.mount
// 1.RenderObjectToWidgetElement
void mount(Element? parent, Object? newSlot) {
super.mount(parent, newSlot);
/**
和 componentElement 中的 _firstBuild(StatefulElement会重载这个方法) => rebuild => performBuild => updateChild
最终都会调用到 updateChild
*/
_rebuild();
}
// 2. RootRenderObjectElement
@override
void mount(Element? parent, Object? newSlot) {
// Root elements should never have parents.
super.mount(parent, newSlot);
}
//3. RenderObjectElement
@override
void mount(Element? parent, Object? newSlot) {
super.mount(parent, newSlot);
// 创建RenderObjcet
_renderObject = (widget as RenderObjectWidget).createRenderObject(this);
attachRenderObject(newSlot);
super.performRebuild(); // clears the "dirty" flag
}
//4. Element
void mount(Element? parent, Object? newSlot) {
_parent = parent;
_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;
}
final Key? key = widget.key;
if (key is GlobalKey) {
// RootRenderObjectElement.assignOwner() => 说明是从根传递过来的
owner!._registerGlobalKey(key, this);
}
//更新子的Inherited: _inheritedWidgets = _parent?._inheritedWidgets;
_updateInheritance();
// 这里是通知 _notificationTree = _parent?._notificationTree;
attachNotificationTree();
}
3.1 接着看RenderObjectToWidgetElement 的 _rebuild();
// 1. RenderObjectToWidgetElement
void _rebuild() {
// _rootChildSlot : 其实就是一个静态的 Object()对象
// widget as RenderObjectToWidgetAdapter<T>).child 就是 我们自定义的 MyAPP2
//
_child = updateChild(_child, (widget as RenderObjectToWidgetAdapter<T>).child, _rootChildSlot);
}
// 2. Element
Element? updateChild(Element? child, Widget? newWidget, Object? newSlot) {
if (newWidget == null) {
if (child != null) {
deactivateChild(child);
}
return null;
}
final Element newChild;
if (child != null) {
bool hasSameSuperclass = true;
if (hasSameSuperclass && child.widget == newWidget) {
// We don't insert a timeline event here, because otherwise it's
// confusing that widgets that "don't update" (because they didn't
// change) get "charged" on the timeline.
if (child.slot != newSlot) {
updateSlotForChild(child, newSlot);
}
newChild = child;
} else if (hasSameSuperclass && Widget.canUpdate(child.widget, newWidget)) {
// 更新Widget
// Element: 会: child.widget = newWidget;
// 其他的Element(SingleChildRenderObjectWidget): 一般会先更新自己,然后再 updateChild
// 仅仅更新了Widget, child (Element) 还是老的Element
child.update(newWidget);
newChild = child;
} else {
deactivateChild(child);
newChild = inflateWidget(newWidget, newSlot);
}
} else {
// child == nil的时候进入这里
newChild = inflateWidget(newWidget, newSlot);
}
return newChild;
}
// Element 类
// widget : MYAPP2 ,newSlot : _rootChildSlot
Element inflateWidget(Widget newWidget, Object? newSlot) {
// MYAPP2 key 是 null
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);
return updatedChild!;
}
}
// 往下走 MYAPP2 调用createElement 返回对应的 element
final Element newChild = newWidget.createElement();
// 接下来就是 MYAPP2 element 去执行挂载
// .... 这样就会一直去挂载,直到
newChild.mount(this, newSlot);
return newChild;
}
4. 我们接下来看看 markNeedsBuild
// Element 类
void markNeedsBuild() {
_dirty = true;
// owner来收集这些Element
owner!.scheduleBuildFor(this);
}
// BuildOwner
void scheduleBuildFor(Element element) {
// 收集这些Element
_dirtyElements.add(element);
element._inDirtyList = true;
}