setState之后
以下代码会删除断言等不是核心的代理
State > setState
@protected
void setState(VoidCallback fn) {
///执行setState包裹的匿名函数
final dynamic result = fn() as dynamic;
///将当前element标记为dirty,需要更新的
_element.markNeedsBuild();
}
Element > markNeedsBuild
标记当前element为dirty
void markNeedsBuild() {
/// 如果不是活跃的组件不需要更新
if (_lifecycleState != _ElementLifecycle.active) {
return;
}
/// 如果组件已标记为dirty则不需要重复标记
if (dirty) {
return;
}
/// 将组件标记为dirty
_dirty = true;
owner!.scheduleBuildFor(this);
}
BuildOwner > scheduleBuildFor
void scheduleBuildFor(Element element) {
///判断当前更新的element当前已在_dirtyElements数组里
if (element._inDirtyList) {
_dirtyElementsNeedsResorting = true;
return;
}
if (!_scheduledFlushDirtyElements && onBuildScheduled != null) {
_scheduledFlushDirtyElements = true;
onBuildScheduled();
}
///将当前的element添加到_dirtyElements
_dirtyElements.add(element);
/// 向脏元素列表添加这个element
element._inDirtyList = true;
}
Element 和 RenderObject更新
WidgetsBinding > drawFrame
Flutter 会在下一帧的时候调用drawFrame
void drawFrame() {
if (renderViewElement != null)
//这里执行的是dirtyElement的更新
buildOwner.buildScope(renderViewElement);
//这里更新的RenderObject的更新
super.drawFrame();
}
BuildOwner > buildScope
这里的BuildOwner就是上面把element添加到dirtyElements里的owner
void buildScope(Element context, [ VoidCallback callback ]) {
...
while (index < dirtyCount) {
///对每个dirtyElement执行rebuild
_dirtyElements[index].rebuild();
index += 1;
}
...
}
Element > rebuild
void rebuild() {
if (!_active || !_dirty)
return;
///
performRebuild();
}
ComponentElement > performRebuild
这里是ComponentElement的更新
void performRebuild() {
Widget built;
try {
///这里的built就是StatelessWidget的build和StatefulWidget State的build所返回的widget
built = build();
} catch (e, stack) {
} finally {
///这里设置当前dirty为false,防止后面update的时候递归
_dirty = false;
}
try {
///更新子element,这里的_child是子element, built是当前element的build返回的widget,也就是子widget,它们的关系会在下面其他理清
_child = updateChild(_child, built, slot);
} catch (e, stack) {
}
}
Element > updateChild
Element updateChild(Element child, Widget newWidget, dynamic newSlot) {
if (newWidget == null) {
if (child != null)
///如果build返回的widget是null,但是当前element不为null的话销毁这个element
deactivateChild(child);
return null;
}
Element newChild;
///如果child不为null则判断是否需要更新或重新创建
if (child != null) {
bool hasSameSuperclass = true;
if (hasSameSuperclass && child.widget == newWidget) {
if (child.slot != newSlot)
updateSlotForChild(child, newSlot);
///如果element的widget和新build返回的widget相同的话则返回当前element
///这里可以发现两个widget相等的情况下会少出发child.update(newWidget)
///这里可以用const Widget来优化
newChild = child;
} else if (hasSameSuperclass && Widget.canUpdate(child.widget, newWidget)) {
if (child.slot != newSlot)
updateSlotForChild(child, newSlot);
///如果element的widget和新build返回的widget的runTimeType和key相同的话
///则用新的widget更新到element
child.update(newWidget);
newChild = child;
} else {
///销毁当前element
deactivateChild(child);
///用newWidget的createElement创建一个新的element
newChild = inflateWidget(newWidget, newSlot);
}
} else {
newChild = inflateWidget(newWidget, newSlot);
}
return newChild;
}
其他
Element里的_owner
这里的_owner是所有element使用的都是同一个owner
初始化 | WidgetsBinding > initInstances
@override
void initInstances() {
super.initInstances();
_instance = this;
_buildOwner = BuildOwner();
...
}
绑定到顶层element | RenderObjectToWidgetAdapter > attachToRenderTree
RenderObjectToWidgetElement<T> attachToRenderTree(BuildOwner owner, [ RenderObjectToWidgetElement<T> element ]) {
if (element == null) {
owner.lockState(() {
element = createElement();
///这里设置了顶层element的owner
element.assignOwner(owner);
});
owner.buildScope(element, () {
element.mount(null, null);
});
SchedulerBinding.instance.ensureVisualUpdate();
} else {
element._newWidget = this;
element.markNeedsBuild();
}
return element;
}
子element引用父element的owner | Element > mount
@mustCallSuper
void mount(Element parent, dynamic newSlot) {
_parent = parent;
_slot = newSlot;
_depth = _parent != null ? _parent.depth + 1 : 1;
_active = true;
///为每个子element引用夫element的owner
if (parent != null) // Only assign ownership if the parent is non-null
_owner = parent.owner;
final Key key = widget.key;
if (key is GlobalKey) {
key._register(this);
}
_updateInheritance();
}
Element的widget和 _child 和build 之间的关系
测试代码
class First extends StatefulWidget {
@override
_FirstState createState() => _FirstState();
}
class _FirstState extends State<First> {
@override
Widget build(BuildContext context) {
return Second();
}
}
class Second extends StatefulWidget {
@override
_SecondState createState() => _SecondState();
}
class _SecondState extends State<Second> {
@override
Widget build(BuildContext context) {
return Container();
}
}
/// FirstStatefulElement > widget = First
/// FirstStatefulElement > build() = Second
/// FirstComponentElement > _child = SecondElement
/// SecondStatefulElement > widget = Second
/// FirstComponentElement._child 和 FirstComponentElement Build() = SecondStatefulElement 和 Second
///_child = updateChild(_child, built, slot); 等价于 SecondElement = updateChild(SecondElement, Second, slot)