Flutter 核心原理与混合开发模式

Flutter 核心原理与混合开发模式(1) 分享一份工作1到5年以上的Android程序员架构进阶学习路线体系,希望能对那些还在从事Android开发却还不知道如何去提升自己的,还处于迷茫的朋友!阿里P7级Android架构师技术脑图;查漏补缺,体系化深入学习提升**全套体系化高级架构视频;**七大主流技术模块,视频+源码+笔记有任何问题,欢迎广大网友一起来交流《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取![外链图片转存中…(img-Mz1m8z2I-1712262602938)] 阅读详情

原创 airingdeng [腾讯音乐技术团队]

在 「Fan 直播」的 Flutter 混合开发实践中,我们总结了一些 Flutter 混合开发的经验。本文第一篇章将从 Flutter 原理出发,详细介绍 Flutter 的绘制原理,借由此在第二章来对比三种跨端方案;之后再进入第三篇章 Flutter 混合开发模式的讲解,主要是四种不同的 Flutter 混合模式的原理分析;最后的第四篇章,简单分享一下混合工程的工程化探索。

“唯有深入,方能浅出”,对于一门技术,只有了解的深入,才能用最浅显、通俗的话语描述出。在此之前,我写过一些 Flutter 的文章,但性质更偏向于学习笔记与源码阅读笔记,因此较为晦涩,且零碎繁乱。本文作为阶段性的总结,我尽可能以浅显易懂的文字、循序渐进地来分享 Flutter 混合开发的知识,对于关键内容会辅以源码或源码中的关键函数来解读,但不会成段粘贴源码。源码学习的效果主要在于自身,所以若对源码学习感兴趣的,可以自行阅读 Framework 与 Engine 的源码,也可以阅读我过往的几篇文章。

好了,那废话不多说,直接开始吧!

1. Flutter 核心原理

1.1 Flutter 架构

Flutter架构

注:此图引自 Flutter System Overview

传统惯例,只要说到 Flutter 原理的文章,在开头都会摆上这张图。不论讲的好不好,都是先摆出来,然后大部分还是靠自行领悟。因为这张图实在太好用了。

摆出这张图,还是简单从整体上来先认识了一下什么是 Flutter,否则容易陷入“盲人摸象”的境地。

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

  1. Embedder:操作系统适配层,实现渲染 Surface 设置、线程设置等。
  2. Engine:实现 FLutter 渲染引擎、文字排版、事件处理、Dart 运行时等功能。包括了 Skia 图形绘制库、Dart VM、Text 等,其中 Skia 和 Text 为上层接口提供了调用底层渲染和排版的能力。
  3. Framework:是一个用 Dart 实现的 UI SDK,从上之下包括了两大风格组件库、基础组件库、图形绘制、手势识别、动画等功能。

至于更多详情,这张图配合源码食用体验会更好。但由于本文不是源码解析,所以这个工作本文就不展开了。接下来,我会以 Flutter 绘制流程为例,来讲解 Flutter 是如何工作的。这也能更好地帮助你理解源码的思路。

1.2 Flutter 绘制原理

Flutter 绘制流程总结了一下大体上如下图所示:

flutter-render.png

首先是用户操作,触发 Widget Tree 的更新,然后构建 Element Tree,计算重绘区后将信息同步给 RenderObject Tree,之后实现组件布局、组件绘制、图层合成、引擎渲染。

作为前置知识,我们先来看看渲染过程中涉及到的数据结构,再来具体剖析渲染的各个具体环节。

1.3 Flutter 渲染过程中的数据结构

Data Model

渲染过程中涉及到的关键的数据结构包括三棵树和一个图层,其中 RenderObject 持有了 Layer,我们重点先看一下三棵树之间的关系。

举个栗子,比如有这么一个简单的布局:

布局

那么对应的三棵树之间的关系如下图所示:

三棵树
1.3.1 Widget Tree
Widget Tree

第一棵树,是 Widget Tree。它是控件实现的基本逻辑单位,是用户对界面 UI 的描述方式。

需要注意的是,Widget 是不可变的(immutable),当视图配置信息发生变化时,Flutter 会重建 Widget 来进行更新,以数据驱动 UI 的方式构建简单高效。

那为什么将 Widget Tree 设计为 immutable?Flutter 界面开发是一种响应式编程,主张“simple is fast”,而由上到下重新创建 Widget Tree 来进行刷新,这种思路比较简单,不用额外关系数据更变了会影响到哪些节点。另外,Widget 只是一个配置是数据结构,创建是轻量的,销毁也是做过优化的,不用担心整棵树重新构建带来的性能问题。

1.3.2 Element Tree
Element Tree

第二棵树,Element Tree。它是 Widget 的实例化对象(如下图,Widget 提供了 createElement 工厂方法来创建 Element),持久存在于运行时的 Dart 上下文之中。它承载了构建的上下文数据,是连接结构化的配置信息到最终完成渲染的桥梁。

之所以让它持久地存在于 Dart 上下文中而不是像 Widget 重新构建,因为 Element Tree 的重新创建和重新渲染的开销会非常大,所以 Element Tree 到 RenderObject Tree 也有一个 Diff 环节,来计算最小重绘区域。

@immutableabstract class Widget extends DiagnosticableTree {  /// Initializes [key] for subclasses.  const Widget({ this.key });  final Key key;    @protected  @factory  Element createElement();  /// ... 省略其他代码}

需要注意的是,Element 同时持有 Widget 和 RenderObject,但无论是 Widget 还是 Element,其实都不负责最后的渲染,它们只是“发号施令”,真正对配置信息进行渲染的是 RenderObject。

1.3.3 RenderObject Tree
RenderObject Tree

第三棵树,RenderObject Tree,即渲染对象树。RenderObject 由 Element 创建并关联到Element.renderObject 上(如下图),它接受 Element 的信息同步,同样的,它也是持久地存在 Dart Runtime 的上下文中,是主要负责实现视图渲染的对象。

RenderObject get renderObject {  RenderObject result;  void visit(Element element) {    assert(result == null); // this verifies that there's only one child    if (element is RenderObjectElement)      result = element.renderObject;    else      element.visitChildren(visit);  }  visit(this);  return result;}

RenderObject Tree 在 Flutter 的展示过程分为四个阶段:

  1. 布局
  2. 绘制
  3. 合成
  4. 渲染

其中,布局和绘制在 RenderObject 中完成,Flutter 采用深度优先机制遍历渲染对象树,确定树中各个对象的位置和尺寸,并把它们绘制到不同的图层上。绘制完毕后,合成和渲染的工作则交给 Skia 处理。

那么问题来了,为什么是三棵树而不是两棵?为什么需要中间的 Element Tree,由 Widget Tree 直接构建 RenderObject Tree 不可以吗?

理论上可以,但实际不可行。因为如果直接构建 RenderObject Tree 会极大地增加渲染带来的性能损耗。因为 Widget Tree 是不可变的,但 Element 却是可变的。实际上,Element 这一层将 Widget 树的变化做了抽象(类似 React / Vue 的 VDOM Diff),只将真正需要修改的部分同步到 RenderObject Tree 中,由此最大程度去降低重绘区域,提高渲染效率。可以发现,Flutter 的思想很大程度上是借鉴了前端响应式框架 React / Vue。

Flutter 核心原理与混合开发模式,张口就来 跨端方案1所谓 Web 容器,即是基于 Web 相关技术通过浏览器组件来实现界面和功能,包括我们通常意义上说的基于 WebView 的 “H5”、Cordova、Ionic、微信小程序。这类 Hybrid 开发模式,只需要将开发一次 Web,就可以同时在多个系统的浏览器组件中运行,保持基本一致的体验,是迄今为止热度很高的跨端开发模式。而 Web 与 原生系统之间的通信,则通过 JSBridge 来完成,原生系统通过 JSBridge 接口暴露能力给 Web 调用。 阅读详情

相关推荐

Flutter 核心原理与混合开发模式,Android开发面试宝典

希望本文对你有所启发,有任何面试上的建议也欢迎留言分享给大家。好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,可以加一下下面的技术群。来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。这里放一下资料获取方式:GitHub好了~如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。

905

Android与Flutter面试核心:从原理到实战的进阶指南

在移动开发领域,掌握核心技术原理是应对面试与工程实践的关键。理解JVM内存模型、垃圾回收机制、多线程并发等计算机基础,是深入Android性能优化的基石。Handler消息机制、Binder通信原理、View绘制流程等系统级知识,构成了高性能应用开发的核心框架。随着跨平台技术的发展,Flutter的Widget三棵树、状态管理及Dart异步模型,成为现代移动开发者的必备技能。这些原理知识最终服务于内存优化、UI渲染、包体积缩减等实际工程场景,帮助开发者构建流畅、稳定的应用。本文聚焦Android与Flutt

weixin_31896061的博客 341

Flutter自绘引擎:跨端开发的高性能解决方案

自绘引擎是现代跨端开发中的关键技术,它通过统一渲染层实现像素级一致的UI表现。其核心原理是绕过平台原生控件,直接控制渲染管线,这带来了性能可控性和跨平台扩展性两大优势。在移动应用开发中,自绘引擎解决了传统Hybrid方案性能低下和React Native桥接通信瓶颈等问题。Flutter作为典型实现,采用Skia图形库和Dart语言,支持iOS/Android/Web等多平台,特别适合需要快速迭代和高性能渲染的场景。通过工业级验证的Skia引擎和JIT+AOT双模式Dart运行时,开发者既能获得亚秒级热重载

weixin_30417487的博客 602

Flutter核心原理与混合开发模式

Widget是Flutter中用于构建用户界面的基本元素,可以是简单的文本或图像,也可以是复杂的布局和交互组件。自绘UI:与传统的UI框架不同,Flutter采用了自绘UI的方式来实现界面的绘制。Flutter是一种跨平台的移动应用开发框架,它采用了自绘UI的方式来实现高性能、高度定制化的用户界面。上述代码创建了一个包含5个元素的整型数组,并使用Lambda表达式初始化每个元素的值。数组的索引从0开始,即第一个元素的索引为0。需要注意的是,这只是声明了一个数组的变量,还需要初始化才能使用。

IdcEditor的博客 172

深入了解移动开发领域的跨平台开发模式

移动应用市场中,iOS和Android两大系统占据99%以上份额(StatCounter 2023数据)。传统原生开发需为两个系统编写独立代码(Java/Kotlin for Android,Swift/Objective-C for iOS),导致开发成本高、迭代周期长。本文聚焦“跨平台开发模式”,覆盖主流技术方案的原理、适用场景及实战方法,帮助开发者降低多端开发门槛。本文从“为什么需要跨平台”切入,用故事引出核心概念;通过生活比喻解释三种主流模式;结合代码示例对比技术实现;最后总结选型策略与未来趋势。

移动开发前沿的博客 524

【数学基础】基于欧拉角表达的旋转顺序

欧拉角旋转顺序

FalschxMico 1384

STM32F4驱动海康工业相机实战:从PWM信号到精准触发拍照(附完整代码)

本文详细介绍了如何使用STM32F4开发板驱动海康工业相机,实现PWM信号精准触发拍照的完整方案。从硬件连接到PWM信号生成,再到相机触发配置与延迟补偿,提供了实战经验和完整代码,帮助开发者解决工业相机硬件触发中的关键问题。

weixin_33716941的博客 694

北航论文模板:解决XeLaTeX中Font shape'TU/SimSun(1)/b/n' undefined(font) using 'TU/SimSun(1)/m/n' instead

北航论文模板:解决XeLaTeX中Font shape ‘TU/SimSun(1)/b/n’ undefined(font) using ‘TU/SimSun(1)/m/n’ instead 问题 问题描述: 在使用北航论文模板时,产生了warning:Font shape 'TU/SimSun(1)/b/n' undefined(font) using 'TU/SimSun(1)/m/n' i...

qq_39560620的博客 1万+

Unity中的Timeline

Timeline与动画系统类似,但是它可以针对多个物体做出一系列多个动画,它可以创建多个轨道,对象激活与隐藏轨道,动画轨道,声音轨道等。每个轨道都可以单独编辑,轨道内的不同资源可以排列并且融合

L的博客 1万+

【RV1126/RV1109学习笔记】#基础篇#(2)基础入门使用

一、调试方式 1、串口调试 2、ADB调试 3、网络调试 二、基础外设使用 音频使用(aplay,arecord,amixer) 三、WIFI连接 四、屏幕背光控制

丨晋丨 1854

【QNX+Android虚拟化方案】00 - 系列文章链接汇总

【QNX+Android虚拟化方案】00 - 系列文章链接汇总

|~~~热爱生活、努力学习的小伙汁~~~| 1万+

Vue3 - Element Plus上传组件el-upload上传多个文件时,让on-change监听事件仅执行一次并获取最终文件列表方法(开启多选文件并手动上传,拿到文件列表统一循环调用接口上传)

vue3,elementplus,Upload上传,el-upload,文件上传组件,上传组件on-change里执行多次,取消自动上传后change重复执行问题,upload上传多个文件后导致on-change执行多次拿不到最终文件列表,Element-plus的upload组件on-change不断执行怎么办,上传多个文件多次执行调用,上传多个文件时如何只执行一次on-change方法拿到最终的文件列表,vue3elementplus上传组件开启多个上传后导致change方法执行好几次,仅调用一

🏆 前端领域优质创作者 1万+

Sigrity Power DC Resitance Network Model Generation模式生成电阻SPICE模型操作指导

Sigrity Power DC Resitance Network Model Generation模式是用于提取负载每个pin电阻SPICE模型的,结果以spice网表形式展现,仍然以Motherboard.spd为例进行说明。目的是模拟实际情况,via的孔壁电镀1mil,中间是空心的,让via不完全被填充金属成为实心via。Upper/lower Tolerance:上下公差,设置为5%,也就是压降允许的范围。P/F Mode:通过/失败模式,选择Worst,最差的情况。

weixin_54787054的博客 416

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

上一篇: Android应用架构的发展和实践
下一篇: 程序员垃圾简历长什么样?这能找到工作就怪了
Python_林一
博客等级 码龄7年 876粉丝 510原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值