文章目录
Flutter Framework
视图树的创建与管理机制、布局、渲染核心框架
视图树
- Widget => 为Element提供配置信息
- Element => Flutter创建Element的可见树, 同时持有Widget和RenderObject
- RenderObject => 渲染树中的一个对象
渲染机制
调用runApp(rootWidget),将rootWidget传给rootElement,做为rootElement的子节点,生成Element树,由Element树生成Render树
runApp(首次执行)
void runApp(Widget app) {
WidgetsFlutterBinding.ensureInitialized()
..attachRootWidget(app)
..scheduleWarmUpFrame();
}
runApp(rootWidget) => attachRootWidget(rootWidget) => attachToRenderTree() => element.mount() => _rebuild() => updateChild()
1. WidgetsFlutterBinding
WidgetsFlutterBinding混入了不少的其他的Binding
- BindingBase 那些单一服务的混入类的基类
- GestureBinding framework手势子系统的绑定,处理用户输入事件
- ServicesBinding 接受平台的消息将他们转换成二进制消息,用于平台与flutter的通信
- SchedulerBinding 调度系统,用于调用Transient callbacks(Window.onBeginFrame的回调)、Persistent callbacks(Window.onDrawFrame的回调)、Post-frame callbacks(在Frame结束时只会被调用一次,调用后会被系统移除,在Persistent callbacks后Window.onDrawFrame回调返回之前执行)
- PaintingBinding 绘制库的绑定,主要处理图片缓存
- SemanticsBinding 语义化层与Flutter engine的桥梁,主要是辅助功能的底层支持
- RendererBinding 渲染树与Flutter engine的桥梁
- WidgetsBinding Widget层与Flutter engine的桥梁
持有BuildOwner、PipelineOwner
-
BuildOwner
BuildOwner是Widget framework的管理类, 该类跟踪哪些小部件需要重新构建,并处理应用于整个小部件树的其他任务,比如管理树的非活动元素列表
-
PipelineOwner
管理真正需要绘制的View, 对RenderObjectTree中发生变化节点的进行flush操作, 最后交给底层引擎渲染
2. attachRootWidget
-
1.attachRootWidget(app) 方法创建了Root[Widget](也就是 RenderObjectToWidgetAdapter)
void attachRootWidget(Widget rootWidget) { _renderViewElement = RenderObjectToWidgetAdapter<RenderBox>( container: renderView, debugShortDescription: '[root]', child: rootWidget ).attachToRenderTree(buildOwner, renderViewElement); }
-
2.紧接着调用attachToRenderTree方法创建了 Root[Element]
RenderObjectToWidgetElement<T> attachToRenderTree(BuildOwner owner, [RenderObjectToWidgetElement<T> element]) { if (element == null) { owner.lockState(() { element = createElement(); //创建rootElement element.assignOwner(owner); //绑定BuildOwner }); owner.buildScope(element, () { //子widget的初始化从这里开始 element.mount(null, null); // 初始化子Widget前,先执行rootElement的mount方法 }); } else { ... } return element; }
-
3.Root[Element]尝试调用mount方法将自己挂载到父Element上,因为自己就是root了,所以没有父Element,挂空了
owner.buildScope(element, () { //子widget的初始化从这里开始 element.mount(null, null); // 初始化子Widget前,先执行rootElement的mount方法 });
-
4.mount的过程中会调用Widget的createRenderObject,创建了 Root[RenderObject]
void mount(Element parent, dynamic newSlot) { _parent = parent; //持有父Element的引用 _slot = newSlot; _depth = _parent != null ? _parent.depth + 1 : 1;//当前节点的深度 _active = true; if (parent != null) // Only assign ownership if the parent is non-null _owner = parent.owner; //每个Element的buildOwner,都来自父类的BuildOwner, 这样可以保证一个ElementTree,只由一个BuildOwner来维护 ... } @override void mount(Element parent, dynamic newSlot) { super.mount(parent, newSlot); _renderObject = widget.createRenderObject(this); attachRenderObject(newSlot); _dirty = false; }
-
5.我们将app作为参数传给了Root[Widget](也就是 RenderObjectToWidgetAdapter),app[Widget]也就成了为root[Widget]的child[Widget]
-
6.调用owner.buildScope,开始执行子Tree的创建以及挂载(与更新流程一致, 见更新)
-
7.调用createElement方法创建出Child[Element]
Element inflateWidget(Widget newWidget, dynamic newSlot) { final Key key = newWidget.key; if (key is GlobalKey) { final Element newChild = _retakeInactiveElement(key, newWidget);