详解flutter刷新流程,让你的应用更流畅

本文已授权公众号【缦图技术团队】发布

详解flutter刷新流程,让你的应用更流畅

一、概述

Flutter 是谷歌推出的高性能、跨端UI框架,可以通过一套代码,支持 iOSAndroidWindows/MAC/Linux 等多个平台,且能达到原生性能。Flutter 也可以与平台原生代码进行混合开发,其更新迭代速度很快,技术发展也日趋成熟,如今已经有很多公司在使用这种新跨端技术。我们知道在 flutter 中可以使用 setState() 来刷新 StatefulWidget 的 UI,这会遍历调用子 Widget 的 build() 重构视图。当一个页面内容比较复杂时,会包含多个 widget,如果直接调用根组件的 setState(),会遍历所有子 Widget 的 build(),刷新整个页面,这样会造成很多不必要的开销,刷新的成本相对较大。如果数据很多接口响应又慢的话,还会有界面闪烁的现象。那么 flutter 到底是如何实现界面刷新的,调用 setState({})后 flutter framework 到底做了哪些操作?接下来我们一起来揭开 flutter 刷新界面的神秘面纱。

二、Flutter 渲染中的三棵树

在了解flutter的刷新机制之前,先来看看flutter渲染过程中的三棵树。在Flutter的渲染过程中由WidgetElementRenderObject这个三个元素组成三棵树。Widget控件树,Element 元素树,RenderObject 渲染树。Widget内部调用 createElement()会创建对应的 ElementElement内部调用 createRenderObject()会创建对应的 RenderObject,所以我们只需要关心 Widget 就可以快速的构建视图界面了。为什么使用三棵树而不是 Widget RenderObject 两棵树呢?这里是为了复用 Element 提升渲染性能,因为 Widget 面向业务它的改变会很频繁,如果根据 Widget 直接生成 RenderObject 会导致渲染性能下降。

详解flutter刷新流程,让你的应用更流畅_第1张图片 flutter 三棵树依赖关系

RenderObject 渲染树在上屏前会生成一棵 Layer 树去进行屏幕渲染。

三、刷新流程分析

在开始流程分析之前,先上个图来梳理下整个刷新流程,脑海里对整体先有个初步认识,这样再跟着下面的源码一步步往里深入分析,思路会更加清晰一些:

详解flutter刷新流程,让你的应用更流畅_第2张图片 setState() 刷新流程

对整体的刷新流程有了大概的认识之后,我们对照着上面这个图的流程来看看调用setState({})之后,系统具体都做了哪些操作:

注:

setState() 源码位于 flutetr_sdk/packages/flutter/lib/src/widgets/framework.dart 文件中

本文源码基于 Flutter 3.3.8 Dart 2.18.4 • DevTools 2.15.0

  @protected
  void setState(VoidCallback fn) {
    assert(fn != null);
    assert(() {
      if (_debugLifecycleState == _StateLifecycle.defunct) {
        throw FlutterError.fromParts([
    			// 省略不重要代码
        ]);
      }
      if (_debugLifecycleState == _StateLifecycle.created && !mounted) {
        throw FlutterError.fromParts([
    			// 省略不重要代码
        ]);
      }
      return true;
    }());
    final Object? result = fn() as dynamic;
    ...
    // 省略不重要代码
    _element!.markNeedsBuild();
  }

setState() 中传入的回调函数是立刻同步执行的,不能是异步的。该方法前面主要是 assert 部分的一些校验逻辑,不允许传入的回调函数为null且不能为异步函数,这里有一个点需要注意:在 widget 构造函数中以及 dispose 调用之后,不允许再调用 setState() 方法去刷新界面,可以在调用前考虑使用 mounted 标志来检测该 widget 是否还挂载在 

你可能感兴趣的:(flutter开发,flutter,刷新)