Flutter Framework层UI绘制finalizeTree()方法(四)
本文记录自己学习 Flutter 绘制所见源码,并不是全面详细的解析 Blog。
Flutter 源码环境:1.22.1
//此方法由[handleDrawFrame]调用,当需要布置和绘制框架时,引擎会自动调用该方法。
void drawFrame() {
...
try {
if (renderViewElement != null)
// 1. 调用 buildScope()
buildOwner.buildScope(renderViewElement);
//2.调用super.drawFrame();
super.drawFrame();
// 3. 调用finalizeTree()
buildOwner.finalizeTree();
} finally {
...
}
...
}
今天来看 drawFrame() 的最后一个方法 finalizeTree()。
3 finalizeTree()
flutter/lib/src/widgets/framework.dart
void finalizeTree() {
Timeline.startSync('Finalize tree', arguments: timelineArgumentsIndicatingLandmarkEvent);
try {
lockState(() {
_inactiveElements._unmountAll(); // this unregisters the GlobalKeys
});
} catch (e, stack) {
// Catching the exception directly to avoid activating the ErrorWidget.
// Since the tree is in a broken state, adding the ErrorWidget would
// cause more exceptions.
_debugReportException(ErrorSummary('while finalizing the widget tree'), e, stack);
} finally {
Timeline.finishSync();
}
}
该方法做的功能也比较简单,就是做收尾工作。
主要把_inactiveElements 都进行一次清理,所以使用 GlobalKey 的控件,如果想起到重用控件的效果,必须在同一帧里面完成“借用”,否则就会被清理了。
至此 Flutter drawFrame()的功能基本都清楚了。就是
1.更新赋值绘制控件的参数。
2.依据参数更新 布局,合成,绘制。
3.清理一些无用的元素。
接下来可以理一下 Flutter setState 刷新的流程。
scheduleBuildFor()
void scheduleBuildFor(Element element) {
...
if (element._inDirtyList) {
...
_dirtyElementsNeedsResorting = true;
return;
}
if (!_scheduledFlushDirtyElements && onBuildScheduled != null) {
_scheduledFlushDirtyElements = true;
onBuildScheduled();
}
_dirtyElements.add(element);
element._inDirtyList = true;
...
}
onBuildScheduled()的回调在 WidgetBinding.initInstances 中被初始化。
void initInstances() {
super.initInstances();
...
buildOwner.onBuildScheduled = _handleBuildScheduled;
...
}
接下来 流程就连起来了。
步骤到此,就知道为什么 setState()是怎么刷新界面的了。
评论