注册

Flutter(一)Hello, Flutter!

1. 移动端开发演变过程


1.1 原生开发


原生应用程序是指某一个移动平台(比如iOS或安卓)所特有的应用,使用相应平台支持的开发工具和语言,直接调用系统SDK API。




  • Android原生应用:使用Java或Kotlin直接调用Android SDK开发的应用程序;




  • iOS原生应用:通过Objective-C或Swift语言直接调用iOS SDK开发的应用程序。




主要优势:




  • 可直接无障碍的访问平台全部功能;




  • 速度快、性能高、可以实现复杂动画及绘制,整体用户体验好;




主要缺点:




  • 开发成本高;不同平台必须维护不同代码,人力成本、测试成本大;




  • 内容固定,动态化弱,大多数情况下,有新功能更新时只能发版,但应用上架、审核是需要周期的,这对高速变化的互联网时代来说是很难接受的;




针对动态化和开发成本两个问题,诞生了一些跨平台的动态化框架。👇👇👇👇👇👇


1.2 跨平台技术简介


这里的跨平台指Android和iOS两个平台。根据其原理,主要分为三类:




  • H5+原生(Cordova、Ionic、微信小程序)=> Hybrid/混合开发





  • 原理:APP需要动态变化的内容通过H5来实现,进一步通过原生的网页加载控件WebView (Android)或WKWebView(iOS)来加载。






  • WebView实质上是一个浏览器内核,其JavaScript依然运行在一个权限受限的沙箱中,所以对于大多数系统能力都没有访问权限,如无法访问文件系统、不能使用蓝牙等。所以,对于H5不能实现的功能,都需要原生去做。






  • 核心:混合框架会在原生代码中预先实现一些访问系统能力的API, 暴露给WebView以供JavaScript调用,让WebView成为JavaScript与原生API之间通信的桥梁,主要负责JavaScript与原生之间传递调用消息 => JsBridge(WebView JavaScript Bridge)





  • JavaScript开发+原生渲染 (React Native、Weex、快应用)




这里主要介绍下 React Native 特点




  • 和 React 原理相似,支持响应式编程,开发者只需关注状态转移,不需要关注UI绘制;




  • React 和 React Native 主要的区别在于虚拟DOM映射的对象是什么:





  • React中虚拟DOM最终会映射为浏览器DOM树;






  • RN中虚拟DOM会通过 JavaScriptCore 映射为原生控件树。(两步)







  • 第一步:布局消息传递; 将虚拟DOM布局信息传递给原生;








  • 第二步:原生根据布局信息通过对应的原生控件渲染控件树;






  • 优点:





  • 采用Web开发技术栈,社区庞大、上手快、开发成本相对较低。






  • 原生渲染,性能相比H5提高很多。






  • 动态化较好,支持热更新。





  • 不足:





  • 渲染时需要JavaScript和原生之间通信,在有些场景如拖动可能会因为通信频繁导致卡顿;






  • JavaScript为脚本语言,执行时需要JIT(Just In Time),执行效率和AOT(Ahead Of Time)代码仍有差距;






  • 由于渲染依赖原生控件,不同平台的控件需要单独维护。





( RN架构升级,进行中,解决频繁和原生通信的瓶颈问题。)




  • 自绘UI+原生(QT for mobile、Flutter)





  • QT for mobile(是移动端开发跨平台自绘引擎的先驱,也是烈士。)






  • Flutter 👇👇👇👇👇👇





2. Flutter 介绍


Flutter 是 Google 推出并开源的移动应用框架,主打跨平台、高保真、高性能。


2.1 跨平台自绘引擎


Flutter 与用于构建应用程序的其他框架不同,是因为 Flutter 既不使用 WebView 也不使用操作系统的原生控件。相反,Flutter 自己实现了自绘引擎。这样不仅能保证一套代码可以同时运行在 IOS 和 Android 平台上,还保证了 Android 和 IOS 上 UI 的一致性,而且也可以避免对原生控件依赖带来的限制和高昂的成本维护,也不用和native层做过多的通信,大大提高性能。


Flutter 使用 Skia 作为其2D渲染引擎,Skia 是一个 Google 的2D图形处理函数,包含字符、坐标转换,以及点阵图都有高效能且简介的表现,Skia 是跨平台的,并提供了非常友好的 API ,目前 Google Chrome 浏览器和 Android 均采用 Skia 作为其绘图引擎。


目前 Flutter 默认支持 Android、IOS、Fuchsia(Google新的自研操作系统)、鸿蒙四个移动平台,也支持 Web 开发(Flutter for web)、 PC 、小程序的开发。


2.2 采用Dart语言


这是一个很有意思也很有争议的问题,Flutter为什么选择Dart语言?


① 开发效率高。Dart运行时和编译器支持Flutter两个关键特性的组合:


基于JIT的快读开发周期:Flutter在开发阶段采用JIT模式。这样就避免了每次改动都要进行编译,极大节省了开发时间;并且在iOS和Android模拟器或真机上可以实现毫秒级热重载,并且不会丢失状态。


基于AOT的发布包:Flutter 在发布时间可以通过AOT生成高效的ARM代码以保证应用性能。而JavaScript则不具有这个能力(虽然可以通过打包工具实现)。



目前,程序主要有两种运行方式:静态编译与动态解释。

静态编译:在执行前全部被翻译为机器码

👉 AOT(Ahead of time)即“提前编译”; AOT程序的典型代表是用C/C++开发的应用,他们必须在执行前编译成机器码; 动态解释(解释执行)则是一句一句边翻译边运行

👉 JIT(Just-in-time)即“即时编译”。 JIT的代表则非常多,如JavaScript、Python等。

事实上,所有脚本语言都支持JIT模式。但需要注意的是,JIT和AOT 指的是程序运行方式,和编译语言并非强相关,有些语言既可以以JIT方式运行也可以以AOT方式运行,如Java、Python,他们可以在第一次执行时编译成中间字节码,然后在之后执行时可以直接执行字节码,也许有人会说,中间字节码并非机器码,在程序执行时仍需动态将字节码转换成机器码,是的,这没有错,不过通常我们区分是否为AOT的标准就是看代码在执行前是否需要编译,只要需要编译,无论其编译产物是字节码还是机器码,都属于AOT(不必纠结于概念,概念是为了传达精神而发明的,理解原理即可)。



② 高性能。Flutter提供流畅、高保真的UI体验,为了实现这一点,Flutter中需要能够在每个动画帧中运行大量的代码。这意味着需要一种既能提供高性能的语言,而不会出现丢帧的周期性暂停的问题,而Dart支持AOT,在这一点上可以比JavaScript做的更好。


③ 类型安全。由于Dart 是类型安全的语言,支持静态类型检查,所以可以在编译前发现一些类型错误,并排除潜在问题。这一点对于前端开发者极具吸引力,为了解决JavaScript弱类型的缺点,前端社区出现了很多给JavaScript代码添加静态类型检测的扩展语言和工具,如:微软的TypeScript、Facebook的Flow。而 Dart 本身就支持静态类型,这是他的一个重要优势。


④ 快速内存分配。Flutter框架使用函数式流,这使得它在很大程度上依赖底层内存分配器。因此,拥有一个能够有效的处理琐碎任务的内存分配器将显得十分重要。但其实在内存分配上Dart并没有超越JavaScript,只是Flutter需要,Dart 恰好满足。


⑤ Dart 团队就在 Flutter身边。Dart 语言也是谷歌推出的,由于有Dart团队的积极投入,Flutter团队可以获得更多、更方便的支持。



例如:Dart 最初并没有提供原生二进制文件的工具链(这对于实现可预测的高性能有很大帮助),但是现在它实现了,因为 Dart 团队专门为 Flutter 构建了它。 Dart VM 之前已经针对吞吐量进行了优化,但团队现在正忙于优化VM的延迟,这对于Flutter的工作负载更为重要。



2.3 高性能


Flutter 高性能主要是靠以上刚刚介绍的两点来保证的:


① 采用 Dart 语言开发。Dart 在 JIT(即时编译)模式下,速度与 JavaScript 基本持平,但是 Dart 支持 AOT,当以 AOT 模式运行时,JavaScript 就远远追不上了。速度的提升对高帧率下的数据计算很有帮助。


② 使用自己的渲染引擎来绘制 UI,布局数据由 Dart 语言直接控制,在布局过程中不需要像 RN 那样要在 JavaScript 和 Native 之间通信,这在一些滑动拖动场景下有明显优势,因为在滑动和拖动过程中往往都会引起布局发生变化,所以 JavaScript 需要在 Native 之间不停的同步布局信息,这和在浏览器中要 JavaScript 频繁操作 DOM 所带来的问题是相同的,都会带来比较大的性能开销。


2.4 响应式框架


借鉴 React 响应式的 UI 框架设计思想。中心思想是用 widget 构建你的 UI。 Widget 描述了他们的视图在给定其当前配置和状态时应该看起来像什么。当 widget 的状态发生变化时,widget 会重新构建 UI,Flutter 会对比前后变化的不同, 来确定底层渲染树从一个状态转换到下一个状态所需的最小更改(类似于 React/Vue 中虚拟 DOM 的 diff 算法)。


2.5 多端编译


2.5.1 移动端




  • 打包 Android 并发布手机商店 👉 VSCode





  • 打包命令



    flutter build apk





  • 发布:







  • 注册各大应用市场开发者账号








  • 创建要发布的app信息








  • 按照流程上传






  • 打包 IOS 并发布 Apple Store 👉 XCode





  • 打包命令



    flutter build ios





  • 发布:







  • 注册 Apple 开发者








  • 创建要发布的app信息








  • 配置钥匙串








  • 在xcode配置apple stoer的证书和bundle id








  • xcode>Product>Archive>Distribute App







2.5.2 Web端




  • Flutter 2.x




  • 检查是否支持web开发 $ flutter devices







  • 打包命令


    flutter build web --web-renderer html # 打开速度最快,兼容性好
    flutter build web # 打开速度一般,兼容性好
    flutter build web --web-renderer canvaskit # 打开速度最慢,兼容性好




  • 部署:直接部署到服务器上即可




3. Flutter 框架结构


3.1 移动架构



3.1.1 Framework 框架层


框架层。这是一个纯dart实现的响应式框架,它实现了一套基础库。




  • 底下两层(Foundation、Animation、Painting、Gestures)在Google的一些视频中被合并为一个Dart UI层,对应的是Flutter中的dart:ui包,它是Flutter引擎暴露的底层UI库,提供动画、手势及绘制能力。




  • Rendering 层,是一个抽象层,它依赖于 Dart UI ,这一层会构建一个UI树,当UI有变化时,会计算出有变化的部分,然后更新UI树,最终将UI树绘制到屏幕上,这个过程类似于React中的虚拟dom。Rendering层可以说是Flutter UI 框架的核心,它除了确定每个UI元素的位置、大小之外,还要调用底层dart:ui进行坐标变化和绘制。




  • Widgets层是Flutter提供的一套基础组件




  • Material 和 Cupertino 是 Flutter 提供的两种视觉风格的组件库,Material 安卓风格,Cupertino 是IOS风格。




实际开发过程中,主要都是和最上面的Widgets、Material/Cupertino两层打交道。


3.1.2 Engine 引擎层


纯C++实现的SDK,为Flutter的核心,提供了Flutter核心API的底层实现。其中包括了Dart运行时、Skia引擎、文字排版引擎等,是连接框架和系统(Android/IOS)的桥梁。在代码调用dart:ui库时,调用最终会走到Engine层,然后实现真正的绘制逻辑。


3.1.3 Embedder 嵌入层


嵌入层基本是由平台对应的语言来实现的。例如:在Android上,是由Java和C++ 来实现的,IOS是由Object-C和Object-C++来实现的。


嵌入层为Flutter提供了一个入口,Flutter系统是通过该入口访问底层系统提供的服务,例如输入法、绘制surface等。


3.2 Web端架构



3.3 移动端开发方式架构比较



4. 移动端开发对比


4.1 方案对比



4.2 性能对比



感兴趣 这里 有详细的性能对比介绍,不赘述。


5. Flutter 周边——调试工具


Flutter日志 和 print(); 是比较常用的检查数据的调试方法,但是不支持图形化界面、布局等的检查。👇👇👇👇👇👇


5.1 inspector 插件


可视化和浏览Flutter Widget树的工具。查看渲染树,了解布局信息。


5.2 Dev Tools


5.3 UME


字节 Flutter Infra 团队推出的开源 应用内 调试工具。



Pub.dev 发布地址

pub.flutter-io.cn/packages/fl…

GitHub 开源地址

github.com/bytedance/f…



功能 => UI 检查、代码查看、日志查看、性能工具 ...


服务于 => 设计师、产品经理、研发工程师或质量工程师 ...



  • UI 检查插件包。点选 widget 获取 widget 基本信息、代码所在目录、widget 层级结构、RenderObject 的 build 链与描述的能力,颜色拾取与对齐标尺在视觉验收环节提供有力帮助。






  • 代码查看插件。允许用户输入关键字,进行模糊匹配,对任意代码内容的查看能力。



  • 日志查看。日志信息可通过统一面板提供筛选、导出等。



  • 性能检测包。提供了当前 VM 对象实例数量与内存占用大小等信息。



6. Flutter 周边——学习路线


6.1 学习社区




  • Flutter 中文网 👉 入门文档




  • Flutter 中文社区 👉 入门文档




  • 咸鱼Flutter 👉 可借鉴的架构方案




  • 掘进Flutter 👉 专业性强的博客




  • StackOverflow 👉 问答社区,我遇到的flutter的问题,这里的答案最靠谱




  • 源码及注释 👉 🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️ 最方便开发时查找




6.2 学习路线


1、准备期



  • 目标:



  1. 通过学习 Dart 基本语法,了解 Flutter 中的 Dart 的基本使用;




  2. 学习 Flutter 提供的基础布局和基本内容组件,完成基本页面展示。





2、入门期



3、进阶期



6.3 学习开源项目


UI组件集项目 FlutterUnit


7. Flutter 周边——JS2Flutter



JS 转 Dart => JS2Flutter


作者:得到前端团队
链接:https://juejin.cn/post/7052902682285047821
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录或注册