
正文
flutter异步中setstate flutter out into
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
二、Flutter的渲染机制以及setState()背后的原理
开始FrameWork层会通知Engine表示自己可以进行渲染了,在下一个Vsync信号到来之时,Engine层会通过Windows.onDrawFrame回调Framework进行整个页面的构建与绘制。每次收到渲染页面的通知后,Engine调用Windows.onDrawFrame最终交给_handleDrawFrame()方法进行处理。最后会走到 WidgetsBinding.drawFrame() = buildOwner.buildScope(renderViewElement) = _dirtyElements[index].rebuild() = performRebuild() 这里会触发当前element的widget的build方法= updateChild() 注意这里已经是子节点进行接下来的操作了= 子节点update() = 子节点rebuild() = 子节点performRebuild() ...
小结:所以说在widget树中,越高层的 build() 里调用 setState() 会导致遍历所有的子节点=遍历所有子节点的子节点...
话术总结: setState() 会将当前的 element 标记为 脏 ,并交由 buildOwner ,由 buildOwner 加入自己的 脏列表中 ,等收到页面渲染的通知后(这里流程简略掉),会调用 buildOwenr. buildScope () ,这里会遍历 脏列表 然后每一个都会调用 rebuild() , rebuild() 又会调用 performRebuild() , performRebuild() 则会调用 build() 方法重建当前的 element ,然后调用 updateChild () 开始更新子节点,进而触发子节点的 rebuild() 方法,进行下一轮的周期...一直到最后一个节点
相关问答
Q1: Flutter的setState(状态刷新)
Flutter有两个常用的状态类:
标记为dirty,执行的markNeedsBuild,定义在Element类中:
当前Element节点被标记为dirty,同时调用owner的scheduleBuildFor方法:
将element元素添加到全局的“脏”链表里。
BuildOwner用来管理哪些需要更新的Widget。这个owner最开始被初始化的地方在WidgetsBinding的initInstances方法中,随后初始化了onBuildScheduled方法,对应执行的是_handleBuildScheduled,定义在WidgetsBinding类中:
ensureVisualUpdate 方法定义在SchedulerBinding类中:
在提交下一帧绘制的时候会调用到scheduleFrame方法,提交给引擎绘制,看看scheduleFrame方法,也定义在SchedulerBinding类中:
提交给引擎绘制之后,会收到onDrawFrame的回调,最终执行到_handleDrawFrame方法中,对应的是handleDrawFrame方法,定义在SchedulerBinding类中:
在RendererBinding的initInstances方法中添加了一个回调到这个List中,对应的是RenderBinding的drawFrame方法,对应的节点进行绘制渲染操作。
WidgetsBinding中的drawFrame方法:
看看这里的buildScope方法,定义在BuildOwner方法中。在上面 scheduleBuildFor 方法介绍中有提到:"scheduleBuildFor 是把一个 element 添加到 _dirtyElements 链表,以便当[WidgetsBinding.drawFrame]中调用 buildScope 的时候能够重构 element。onBuildScheduled()是一个 BuildOwner 的回调"。在 drawFrame 中调用 buildOwner.buildScope(renderViewElement)更新 elements。
_dirtyElements列表在遍历的过程中执行rebuild方法,此时将所有标记为dirty的Element节点依次执行rebuild,preformRebuild,build,updateChild,update方法,执行界面更新。完成build,update操作完成之后,后续会将需要绘制的RenderObject添加到需要layout的列表中,等待绘制渲染。所有绘制完成之后将_dirtyElments列表清空,_inDirtyList标记位置为false。
提交给引擎绘制渲染
看看super.drawFrame(),这里就执行到了RendererBinding类中,定义如下:
这里就是将最终需要绘制渲染的画面提交给引擎的地方了,绘制完成之后就在界面显示更新后的视图了。
Q2: Flutter setState为什么不会造成性能困扰?
setState为什么不会造成性能困扰?
图层布局和绘制次数越多CPU开销越多,图层越多内存开销越多,但一个新图层的内存成本远大于一次或者几次布局和绘制的CPU成本,这其实是一个成本考量;具体问题还要具体分析,不是每个组件都适合生成一个新图层;对于那些频繁变动的图层有必要生成新图层,如视频帧所形成的图层,这样避免其重合图层重布局和绘制的边际收益会比其他类型业务的图层大的多
遍历链表寻找relayout boundary,重新布局
遍历链表检查renderObject是否是重绘边界(isRepaintBoundary = true)时,决定合成范围
遍历链表检查renderObject是否是重绘边界(isRepaintBoundary = true),决定绘制范围,或 没有标记isRepaintBoundary的RenderObject时全部绘制
1.setState的节点越远离根部,布局、合成、绘制的开销越少
2.重写isRepaintBoundary可变化绘制范围,可影响开销;如使用 RepaintBoundary 部件
3.绝对宽高可减少开销(constraints.isTight)
flutter异步中setstate的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于flutter out into、flutter异步中setstate的信息别忘了在本站进行查找喔。







