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()是怎么刷新界面的了。
评论
