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

第一步setState

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

1.先執(zhí)行fn();
2.然后調(diào)markNeedsBuild方法

void markNeedsBuild() {
  //對(duì)生命周期處于active狀態(tài)的,直接return;
  if (_lifecycleState != _ElementLifecycle.active)
      return;
  //對(duì)已經(jīng)標(biāo)記dirty=true對(duì)不予重新標(biāo)記。換句話言之,標(biāo)記dirty的已經(jīng)執(zhí)行過(guò)此方法了。
  if (dirty)
      return;
  _dirty = true;//標(biāo)記
  owner!.scheduleBuildFor(this);
}

owner 是BuildOwner的實(shí)例(整個(gè)element tree共享一個(gè)實(shí)例,全局的),owner重要的兩個(gè)變量:

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

scheduleBuildFor方法實(shí)際是將當(dāng)前已經(jīng)標(biāo)記dirty的element添加到_dirtyElements中

void scheduleBuildFor(Element element) {
 if (element._inDirtyList) {
   _scheduledFlushDirtyElements = true;
   return;
 }
 if (!_scheduledFlushDirtyElements && onBuildScheduled != null) {
     _scheduledFlushDirtyElements = true;
     //一個(gè)回調(diào)方法,通知engine下一幀需要坐哪些更新操作
     onBuildScheduled!();
 }
 _dirtyElements.add(element);
 element._inDirtyList = true;
}

此后,WidgetsBinding.drawFrame回調(diào)用BuildOwner.buildScope方法:

void buildScope(Element context, [ VoidCallback? callback ]) {
  if (callback == null && _dirtyElements.isEmpty)
      return;
  try {
    //如有回調(diào),先執(zhí)行回調(diào) 
    if (callback != null) {
      callback();
    }
    //對(duì)「dirty elements」按在「Element Tree」上的深度排序 (即 parent 排在 child 前面) 
    _dirtyElements.sort(Element._sort);
    int dirtyCount = _dirtyElements.length;
    int index = 0;
    //對(duì)_dirtyElements中的元素依次調(diào)用rebuild
    while (index < dirtyCount) {
      _dirtyElements[index].rebuild();
      index += 1;
    }
  } finally {
    //finally
    //遍歷_dirtyElements將元素element的屬性_inDirtyList設(shè)置成false
    //(_inDirtyList在Dirty的集合中 true 代表在,false不在)
    for (Element element in _dirtyElements) {
      element._inDirtyList = false;
    }
    //清空 _dirtyElements
    _dirtyElements.clear();
  }
}

end

注:assert斷言只在調(diào)試模式下生效。故這里省略了assert代碼。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容