导语 | 本文将从选型、简介和运行原理三大部分为你介绍Flutter的相关概念,希望能站在框架设计和实现原理的高度,带领大家去理解Flutter区别其他跨平台解决方案的关键所在。

一、为什么选择Flutter

随着无线时代的来临,怎么样用最标准化的手段能够让更多的人开发这个页面、怎么样能够提供像H5一样标准的页面,成为大前端时代开发者们最关心的事情。

我们把时间线拉长,来看看移动端跨平台技术经过了一个怎样的发展史:下面主要介绍在这个发展过程中跨平台技术有了哪些进步或者做了哪些优化。

Ionic/Cordova(Hybrid): 在技术原理上的核心是,将原生的一些能力通过JSBridge封装给Web来调用,扩充了Web应用能力。但是这种方法有两个不足,一是依赖客户端,二是在性能和体验上都非常依赖于Web端。因此,整体上的体验不可预知。目前这个技术还经常被应用到,例如,当前App内会提供白名单域名和可调用的JSBridge方法,由此来增强H5与客户端交互能力,从而提升App内H5的灵活性。

React Native/Weex: 在原来的Hybrid的JSBridge基础上进行改进,将JavaScript的界面以及交互转化为Native的控件,从而在体验上和原生界面基本一致。但因为是JIT模式,因此需要频繁地在JavaScript与Native之间进行通信,从而会有一定的性能损耗影响,导致体验上与原生会有一些差异。

Flutter: 取长补短,结合了之前的一些优点,解决了与Native之间通信的问题,同时也有了自渲染模式(框架自身实现了一套UI基础框架,与原来的渲染模式基本一致)。从而在体验和性能上相对之前的两种框架表现都较好。

选择Flutter并不是为了代替iOS或者Android,而是做一个技术互补,比如,Flutter负责业务功能,而iOS和Android则负责部分的底层交互提供服务给到Flutter应用,这里大胆预测一下未来跨端技术团队的组成:

二、Flutter简介

Flutter是一款移动应用程序跨平台框架,使用一种语言(Dart)编写的同一份代码可以生成iOS和Android两个高性能、高保真的应用程序。

Flutter目标是使开发人员能够交付在不同平台上都感觉自然流畅的高性能应用程序。兼容滚动行为、排版、图标等方面的差异。那么Flutter是如何编译成原生app的呢?

Flutter不借助原生的渲染能力,而是自己实现了一套与Android和iOS一样的渲染原理,从而在性能上与原生平台保持基本一致。不过这里由于目前 Flutter只是一个UI框架,因此在原生功能方面还是需要依赖原生平台,这也是它存在的一些问题。

三、Flutter运行原理

如前面已提到的那样,Flutter是重写了一整套包括底层渲染逻辑和上层开发语言的完整解决方案。这样不仅可以保证视图渲染在Android和iOS上的高度一致性(即高保真),在代码执行效率和渲染性能上也可以媲美原生App的体验(即高性能)。那Flutter是怎么运行的呢?

我们从图像显示的基本原理说起。

在计算机系统中,图像的显示需要CPU、GPU和显示器一起配合完成:CPU负责图像数据计算,GPU负责图像数据渲染,而显示器则负责最终图像显示。

CPU把计算好的、需要显示的内容交给GPU,由GPU完成渲染后放入帧缓冲区,随后视频控制器根据垂直同步信号(VSync)以每秒60次的速度,从帧缓冲区读取帧数据交由显示器完成图像显示。

操作系统在呈现图像时遵循了这种机制,而Flutter作为跨平台开发框架也采用了这种底层方案。下面有一张更为详尽的示意图来解释Flutter的绘制原理。

可以看到,Flutter关注如何尽可能快地在两个硬件时钟的VSync信号之间计算并合成视图数据,然后通过Skia交给GPU渲染:UI线程使用Dart来构建视图结构数据,这些数据会在GPU线程进行图层合成,随后交给Skia引擎加工成GPU数据,而这些数据会通过OpenGL最终提供给GPU渲染。

在进一步学习Flutter之前,我们有必要了解下构建Flutter的关键技术,即Skia和Dart。

备注

  1. Skia是一款用C++开发的、性能彪悍的2D图像绘制引擎,Skia保证了同一套代码调用在Android和iOS平台上的渲染效果是完全一致的。

  2. Dart是一个专注于前端(mobile/web)UI(用户交互)开发的强类型语言。

在了解了Flutter的基本运作机制后,我们再来深入了解一下Flutter的实现原理。

首先,我们来看一下Flutter的架构图。我希望通过这张图以及对应的解读,你能在开始学习的时候就建立起对Flutter的整体印象。

注:此图引自Flutter System Overview

Flutter架构采用分层设计,从下到上分为三层,依次为Embedder、Engine和Framework。

Embedder是操作系统适配层,实现了渲染Surface设置、线程设置以及平台插件等平台相关特性的适配。从这里我们可以看到,Flutter平台相关特性并不多,这就使得从框架层面保持跨端一致性的成本相对较低。

Engine层主要包含Skia、Dart和Text,实现了Flutter的渲染引擎、文字排版、事件处理和Dart运行时等功能。Skia和Text为上层接口提供了调用底层渲染和排版的能力,Dart则为Flutter提供了运行时调用Dart和渲染引擎的能力。而Engine层的作用,则是将它们组合起来,从它们生成的数据中实现视图渲染。

Framework层则是一个用Dart实现的UI SDK,包含了动画、图形绘制和手势识别等功能。为了在绘制控件等固定样式的图形时提供更直观、更方便的接口,Flutter还基于这些基础能力,根据Material和Cupertino两种视觉设计风格封装了一套UI组件库。我们在开发Flutter的时候,可以直接使用这些组件库。

接下来,以界面渲染过程为例,介绍Flutter是如何工作的

页面中的各界面元素(Widget)以树的形式组织,即控件树。Flutter通过控件树中的每个控件创建不同类型的渲染对象,组成渲染对象树。而渲染对象树在Flutter的展示过程分为三个阶段:布局、绘制、合成和渲染。

(一)布局

Flutter采用深度优先机制遍历渲染对象树,决定渲染对象树中各渲染对象在屏幕上的位置和尺寸。在布局过程中,渲染对象树中的每个渲染对象都会接收父对象的布局约束参数,决定自己的大小,然后父对象按照控件逻辑决定各个子对象的位置,完成布局过程。

为了防止因子节点发生变化而导致整个控件树重新布局,Flutter加入了一个机制——布局边界(Relayout Boundary),可以在某些节点自动或手动地设置布局边界,当边界内的任何对象发生重新布局时,不会影响边界外的对象,反之亦然。

(二)绘制

布局完成后,渲染对象树中的每个节点都有了明确的尺寸和位置。Flutter会把所有的渲染对象绘制到不同的图层上。与布局过程一样,绘制过程也是深度优先遍历,而且总是先绘制自身,再绘制子节点。

以下图为例:节点1在绘制完自身后,会再绘制节点2,然后绘制它的子节点3、4和5,最后绘制节点6。

可以看到,由于一些其他原因(比如,视图手动合并)导致2的子节点5与它的兄弟节点6处于了同一层,这样会导致当节点2需要重绘的时候,与其无关的节点6也会被重绘,带来性能损耗。

为了解决这一问题,Flutter提出了与布局边界对应的机制——重绘边界(Repaint Boundary)。在重绘边界内,Flutter会强制切换新的图层,这样就可以避免边界内外的互相影响,避免无关内容置于同一图层引起不必要的重绘。

重绘边界的一个典型场景是Scrollview。ScrollView滚动的时候需要刷新视图内容,从而触发内容重绘。而当滚动内容重绘时,一般情况下其他内容是不需要重绘的,这时候重绘边界就派上用场了。

(三)合成和渲染

终端设备的页面越来越复杂,因此Flutter的渲染树层级通常很多,直接交付给渲染引擎进行多图层渲染,可能会出现大量渲染内容的重复绘制,所以还需要先进行一次图层合成,即将所有的图层根据大小、层级、透明度等规则计算出最终的显示效果,将相同的图层归类合并,简化渲染树,提高渲染效率。

合并完成后,Flutter会将几何图层数据交由Skia引擎加工成二维图像数据,最终交由GPU进行渲染,完成界面的展示。

四、总结

咱们从各种业界主流跨端方案与Flutter的对比开始,到Flutter的简要介绍以及Flutter的运行机制,并以界面渲染过程为例,从布局、绘制、合成和渲染三个阶段讲述了Flutter的实现原理。相信大家对Flutter已经有一个整体认知,赶快一起上手操作起来吧!

10分钟了解Flutter跨平台运行原理!相关推荐

  1. 地铁供电系统原理图_策划|5分钟读懂地铁运行原理

    原标题:策划|5分钟读懂地铁运行原理 今日摘要 每日小编乘地铁上下班,昨天下午乘坐地铁时突然脑子中闪过一个问题那就是:地铁运行原理是什么?地铁隧道是怎么修建的?人踩在上面会不会有危险呢?今天小编带你一 ...

  2. 10分钟学计算机,电脑运行越来越慢?程序员大牛10分钟教你学会电脑瘦身

    原标题:电脑运行越来越慢?程序员大牛10分钟教你学会电脑瘦身 你的电脑是不是越来越慢?这里让程序员大佬用10分钟时间教你学会给电脑软件瘦身,1分钟了解计算机硬件升级.分分钟让你成为别人眼中的计算机大牛 ...

  3. 【CV】10分钟理解Focal loss数学原理与Pytorch代码

    原文链接:https://amaarora.github.io/2020/06/29/FocalLoss.html 原文作者:Aman Arora Focal loss 是一个在目标检测领域常用的损失 ...

  4. pytorch gather_【CV】10分钟理解Focal loss数学原理与Pytorch代码

    原文链接:https://amaarora.github.io/2020/06/29/FocalLoss.html 原文作者:Aman Arora Focal loss 是一个在目标检测领域常用的损失 ...

  5. 10分钟用Flutter写出摸鱼桌面版App

    简介:大家好,我是枫哥,

  6. boseqc35能不能连电脑_连win7都用不了?轻量级LXLE系统,只要10分钟,旧电脑也能运行如飞!...

    想必每个人家里都有一台旧电脑吧,其实它放在家里真的是很尴尬. 要扔掉吗?好像没这个资本. 要留着当观赏?简直就是碍地方. 要不升级下硬件?那我还不如买新的. 所以,旧电脑该何去何从? 其实说实话,很多 ...

  7. 【宝塔面板建站】10分钟windows宝塔面板一键部署安装wordpress,无需服务器和域名本地运行(保姆级图文)

    目录 傻瓜式一键部署 一键部署 修改本地host 访问域名,启动网站的安装程序 访问建成的网站 总结 『杂记』分享一些实用的技巧方法 安装环境,配置环境教程,推荐实用软件 软件的使用问题. 欢迎关注 ...

  8. 【宝塔面板建站】10分钟windows宝塔面板手动通用部署站点shopxo在线商城,无需服务器和域名本地运行(保姆级图文)

    目录 手动安装,通用方法可以用来安装所有类似的网站 1. 下载shopxo商城源码 2. 添加站点并创建数据库 3. 把第一步下载的网站源码放入我们新建的站点 修改本地host 访问域名,启动网站的安 ...

  9. APP自动化测试系列之Appium介绍及运行原理

    VOL 161 23 2020-09 今天距2021年99天 这是ITester软件测试小栈第161次推文 点击上方蓝字"ITester软件测试小栈"关注我,每周一.三.五早上 0 ...

最新文章

  1. 短序列拼接软件velvet简介
  2. js 获取今天以及前一周/前20天时间
  3. 智能循迹避障小车C语言程序编写思路,基于单片机的智能小车红外避障循迹系统设计与制作...
  4. Kubernetes入门--搭建Kubernetes集群,并启动容器服务
  5. php如何检查图片是否一样,图片检测 - PHP判断真实图片
  6. 使用Apache Kudu和Impala实现存储分层
  7. 巨杉数据库完成数亿元D轮融资,引领金融级分布式数据库发展
  8. 数独基本规则_思维训练|数独入门第五课:唯余解法
  9. layui的table常用方法
  10. linux下多版本opencv共存问题
  11. 给被Access过大问题困扰的网站,提供几种解决方案
  12. Sqlite - constraint failed[0x1555]: UNIQUE constraint failed
  13. Linux服务器开发,开源框架log4cpp和日志模块实现
  14. 爬虫数据储存—CSV文件
  15. pytorch入门篇1 创建tensor
  16. 欢迎IntelliJ IDEA:Maven projects need to be imported: Import Changes Enable Auto-Import
  17. java pass can not be_java – 校验和失败:Kerberos / Spring / Active Directory(2008)
  18. iframe载入完成时的事件监听
  19. 不同网站可以共享cookie吗
  20. 1.3 模拟/dp|大话移动通信

热门文章

  1. Oracle对sum求和进行if,Excel中sumif函数和sumifs函数进行条件求和的异同
  2. linux虚拟机启动网卡命令,命令行下无法联网怎么办,vmware下安装archlinux实现网络连接,实机grub引导启动linux...
  3. c语言gga字符串校验和代码,NMEA-0183协议解析(示例代码)
  4. 【Java】LeetCode 150. 逆波兰表达式求值 (后缀表达式)
  5. tensorflow算法实战:普通的数据训练和迁移学习之后的数据训练进行图像的识别(包括前端页面)
  6. 关于学习Python的一点学习总结(31->继承及多态)
  7. PTA基础编程题目集-6-8 简单阶乘计算
  8. [USACO08JAN]Cell Phone Network G 树形dp
  9. 后缀数组 + Hash + 二分 or Hash + 二分 + 双指针 求 LCP ---- 2017icpc 青岛 J Suffix (假题!!)
  10. 线段树 ---- 线段树维护线段相加+滑动变长窗口 2021牛客多校第7场 F xay loves trees