Flutter框架原理探索

最近参与了Flutter项目模块的开发工作,同时很好奇Flutter内部的原理是什么,于是做了些研究;Flutter是一种“响应式框架”,与React类似;开发人员面向的是Widget,相当于View,没有Activity或者ViewController的概念;再深入探索,Widget其实只是负责配置数据,真正的处理渲染是Element、RenderObject;在理解框架原理之后再使用Flutter确实会生动很多。

一、框架

image.png

还是先从flutter的架构入手,它分为Framework层和Engine层两部分,其中Framework用的是Dart语言,Engine是C++,可以理解为Engine是Framework和Android/iOS的桥梁;先来简单看一下,分析上面的架构图,Framework层有两种样式规则Material(Android)、Cupertino(iOS),开发人员只需关心Widgets(配置信息),在内部进行渲染,其中包括动画、布局、绘制等,将渲染后的图层送入Engine,Engine包括Skia(渲染引擎)文字处理引擎等。

二、渲染流水线

image.png

接下来看下它的渲染流水线,GPU发送Vsync(垂直同步信号)通过Engine层,发送给Framework,Framework接收到信号进行动画、构建、布局、绘制顺序依次进行,最终渲染成Layer Tree 发给GPU;

那么GPU发送Vsync的时机是什么呢?其实在状态发生变化的时候(比如调用State.setState()),此时Framework层会发送Vsync请求给Engine,Engine接收到后告知系统,系统会发送Vsync信号再次通过Engine传递给Framework,Framework接收到信号后进行渲染。

三、布局渲染

image.png

接上面,Render tree来负责布局渲染,过程中需要绘制RenderObject所有子树,所以我们看到的界面是由很多layer组合成的,也就是layer tree。渲染机制是这样的,由GPU发送Vsync信号,通知Framework更新一帧,在UI线程中通过build、layout和paint渲染成Layer Tree,不过此时的渲染结果仍是矢量描述数据,怎么做才能转成让用户看得见的直观视图呢?这就要Engine通过“光栅化”将矢量描述数据生成一个个的像素填充数据;之后传入GPU线程组合Layer Tree,由Skia渲染引擎渲染后送给GPU展示。

四、State生命周期

image.png

State由Statefulwidget创建维护,这里说一下,Statefulewidget不是RenderObjectWidget,也就是它只有Elment没有RenderObject,所以它不能渲染对象,它的职责是维护State,接下来看下State的生命周期。

initState:初始化

build:经过初始化准备好State后,通过build构建,如statelessWidget的build,StatefulWidget State的bulid

deactivate:State从视图树暂时删除,如页面跳转切换

dispose:State从视图树永久移除

didiUpdateConfig:Widget配置变化,如:热修复

setState: 需要更新视图,主动调这个函数

五、原理

image.png

Widget、Element、RenderObject密不可分的关系

在探索构建、布局及绘制原理前,需要先了解Widget、Element、RenderObject的原理及相互关系。Widget会创建自己的Element和RenderObject(并不是每个Widget都有RenderObject,如statefulWidget、statelessWidget),其中Element持有Widget和RenderObject两者的引用;开发者面向的只有Widget,其中Widget是不可变的,Element、RenderObject是可变的,正是这样大大提高的Flutter的性能。

可以理解Widget只是配置信息,实际重点工作都在Element中进行,也就是build阶段,而RenderObject负责布局及绘制的工作;打个比方,Widget是战略部署人员,他只负责部署战略,当一套战略部署需要修改的时候,并不会在原有基础上修改,而是再次制定新的方案,制定完成后将该方案交给实施方案的负责人(Element),此时负责人将新方案与旧的方案加以比较,修改变动点,将具体的方案流程交给(RenderObject)去实现。

再看一下官方的一个例子:

image.png

首先Recanle green Widget下面有一个子Widget Circle blue,绿色组件创建一个Element,再创建一个RenderObject,Element同时持有两者的引用;接下来蓝色组件创建一个Element,并将其挂在到父Element上,再创建一个RenderObject,attach到了父RenderObjuect的插槽,此时渲Render tree建立。

Element负责build阶段,接下来看下Element Tree,Element构建了Element Tree,它的职责就是维护这棵树,可以理解Element Tree是一个“虚拟DOM”,由于DOM每次更新操作都会重新渲染整个DOM,非常耗性能,所以出现了虚拟DOM的概念,也就是通过diff算法,只更新改变的元素就好,大大提升了效率,Element Tree也在flutter中扮演了这样的角色,如statefulWidget通过state.setState通知Element改变,Element对需要更新的Widget标记为dirty状态(被标记dirty的Element会加到dirty list中),表示这个Element需要被重建。

RenderObject负责渲染,在build后,开始布局及绘制(这里涉及到约束布局的概念,下面会说一下),之后生成适量描述数据,这部分就是RenderObject的工作。接下来就是上面提到过的光栅化及Skia处理后送往GPU。

布局约束
image.png

Flutter是盒子约束模型,上图中的每个节点都是RenderObject,父节点会将约束传达给下面的所有子节点,如最大最小宽高;子节点会依据约束定义具体size,将具体的size,如width:200、height:200,告诉父节点一直传给顶部。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容