Flutter setState流程解析!BuildOwner是如何收集「Dirty Elements」的呢?

第一步setState

  @protected
  void setState(VoidCallback fn) {
    final Object? result = fn() as dynamic;
    _element!.markNeedsBuild();
  }

1.先执行fn();
2.然后调markNeedsBuild方法

void markNeedsBuild() {
  //对生命周期处于active状态的,直接return;
  if (_lifecycleState != _ElementLifecycle.active)
      return;
  //对已经标记dirty=true对不予重新标记。换句话言之,标记dirty的已经执行过此方法了。
  if (dirty)
      return;
  _dirty = true;//标记
  owner!.scheduleBuildFor(this);
}

owner 是BuildOwner的实例(整个element tree共享一个实例,全局的),owner重要的两个变量:

final _InactiveElements _inactiveElements = _InactiveElements();
final List<Element> _dirtyElements = <Element>[];

scheduleBuildFor方法实际是将当前已经标记dirty的element添加到_dirtyElements中

void scheduleBuildFor(Element element) {
 if (element._inDirtyList) {
   _scheduledFlushDirtyElements = true;
   return;
 }
 if (!_scheduledFlushDirtyElements && onBuildScheduled != null) {
     _scheduledFlushDirtyElements = true;
     //一个回调方法,通知engine下一帧需要坐哪些更新操作
     onBuildScheduled!();
 }
 _dirtyElements.add(element);
 element._inDirtyList = true;
}

此后,WidgetsBinding.drawFrame回调用BuildOwner.buildScope方法:

void buildScope(Element context, [ VoidCallback? callback ]) {
  if (callback == null && _dirtyElements.isEmpty)
      return;
  try {
    //如有回调,先执行回调 
    if (callback != null) {
      callback();
    }
    //对「dirty elements」按在「Element Tree」上的深度排序 (即 parent 排在 child 前面) 
    _dirtyElements.sort(Element._sort);
    int dirtyCount = _dirtyElements.length;
    int index = 0;
    //对_dirtyElements中的元素依次调用rebuild
    while (index < dirtyCount) {
      _dirtyElements[index].rebuild();
      index += 1;
    }
  } finally {
    //finally
    //遍历_dirtyElements将元素element的属性_inDirtyList设置成false
    //(_inDirtyList在Dirty的集合中 true 代表在,false不在)
    for (Element element in _dirtyElements) {
      element._inDirtyList = false;
    }
    //清空 _dirtyElements
    _dirtyElements.clear();
  }
}

end

注:assert断言只在调试模式下生效。故这里省略了assert代码。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容