Flutter 简介
Flutter 是 Google 推出并开源的移动应用开发框架,主打跨平台、高保真、高性能。开发者可以通过 Dart 语言开发 App,一套代码同时运行在 iOS 和 Android平台。 Flutter 提供了丰富的组件、接口,开发者可以很快地为 Flutter 添加 Native 扩展。由于背靠google,技术上支撑是足够的,且已经支持 iOS、Android、Web、Windows、macOS、Linux、Fuchsia(Google新的自研操作系统)等众多平台,目前GitHub已经有134K的start,具体的地址:https://github.com/flutter/flutter
跨平台演进
一套代码,多端运行,PC时代的Java程序给了我们很好的启示,java之所以可以跨平台,依赖的是JVM,但是我们需要注意的是,跨平台的是Java程序,不是JVM。JVM是用C/C++开发的,是编译后的机器码,不能跨平台,不同平台下需要安装不同版本的JVM。来到移动时代后,跨平台又有哪些演进的过程呢?
Web 容器(H5 + 原生)时代
基于 Web 相关技术通过浏览器组件来实现界面及功能,典型的框架代表有:Cordova(PhoneGap) https://cordova.apache.org/、Ionic https://github.com/ionic-team/ionic-framework和微信小程序
这些框架的主要原理是将 App 中需要动态变动的内容通过HTML5(简称 H5)来实现,通过原生的网页加载控件WebView (Android)或 WKWebView(iOS)来加载。H5代码是运行在 WebView 中,而 WebView 实质上就是一个浏览器内核,其 JavaScript 依然运行在一个权限受限的沙箱中,所以对于大多数系统能力都没有访问权限,如无法访问文件系统、不能使用蓝牙等。为此WebView 中 JavaScript 与原生 API 之间就需要一个通信的桥梁,主要负责 JavaScript 与原生之间传递调用消息,而消息的传递必须遵守一个标准的协议,它规定了消息的格式与含义,我们把依赖于 WebView 的用于在 JavaScript 与原生之间通信并实现了某种消息传输协议的工具称之为 WebView JavaScript Bridge , 简称 JsBridge,它也是混合开发框架的核心。
整体个框架图如下:
采用了 Web 开发技术,社区和资源非常丰富,开发效率也很高。但,一个完整 HTML5 页面的展示要经历浏览器控件的加载、解析和渲染三大过程,性能消耗要比原生开发增加 N 个数量级。如果你的app本身没有复杂的交互或者复杂的动画,使用web容器的方案无可厚非,但是需要大量的跟原生系统交互或者有大量的动画渲染,那么该方案的缺点就显现出来了,那么还有更好的解决方案嘛?答案是有
泛 Web 容器时代(javaScript 开发 + 原生渲染)
泛 Web 容器时代的解决方案优化了 Web 容器时代的加载、解析和渲染这三大过程,把影响它们独立运行的 Web 标准进行了裁剪,以相对简单的方式支持了构建移动端页面必要的 Web 标准,也保证了便捷的前端开发体验;同时,这个时代的解决方案基本上完全放弃了浏览器控件渲染,而是采用原生自带的 UI 组件实现代替了核心的渲染引擎,仅保持必要的基本控件渲染能力,从而使得渲染过程更加简化,也保证了良好的渲染性能。
在这个时代不得不提到大行其道的RN了,React Native (简称 RN )是 Facebook 于 2015 年 4 月开源的跨平台移动应用开发框架,是 Facebook 早先开源的 Web 框架 React 在原生移动应用平台的衍生产物,目前支持 iOS 和 Android 两个平台。RN 使用JSX 语言(扩展后的 JavaScript,主要是可以在 JavaScript 中写 HTML标签)和 CSS 来开发移动应用。
整体的架构图如下:
泛 Web 容器时代主要优点如下:
1,采用 Web 开发技术栈,社区庞大、上手快、开发成本相对较低。
2,原生渲染,性能相比 H5 提高很多。
3,动态化较好,支持热更新。
不足:
1,渲染时需要 JavaScript 和原生之间通信,在有些场景如拖动可能会因为通信频繁导致卡顿。
2,JavaScript 为脚本语言,执行时需要解释执行 (这种执行方式通常称为 JIT,即 Just In Time,指在执行时实时生成机器码),执行效率和编译类语言(编译类语言的执行方式为 AOT ,即 Ahead Of Time,指在代码执行前已经将源码进行了预处理,这种预处理通常情况下是将源码编译为机器码或某种中间码)仍有差距。
3,由于渲染依赖原生控件,不同平台的控件需要单独维护,并且当系统更新时,社区控件可能会滞后;除此之外,其控件系统也会受到原生UI系统限制,例如,在 Android 中,手势冲突消歧规则是固定的,这在使用不同人写的控件嵌套时,手势冲突问题将会变得非常棘手。这就会导致,如果需要自定义原生渲染组件时,开发和维护成本过高。
前面的两个框架都依赖原生进行绘制,那么有没有不依赖原生进行UI绘制的呢?答案是有
自绘引擎时代(自绘UI + 原生)
说起自绘引擎时代,我们应该绕不开QT,这个当初诺基亚用来抵挡android和ios的武器。
Qt 是一个1991年由 Qt Company 开发的跨平台 C++ 图形用户界面应用程序开发框架。2008年,Qt Company 科技被诺基亚公司收购,Qt 也因此成为诺基亚旗下的编程语言工具。2012年,Qt 被 Digia 收购。2014年4月,跨平台集成开发环境 Qt Creator 3.1.0 正式发布,实现了对于 iOS 的完全支持,新增 WinRT、Beautifier 等插件,废弃了无 Python 接口的 GDB 调试支持,集成了基于 Clang 的 C/C++ 代码模块,并对 Android 支持做出了调整,至此实现了全面支持 iOS、Android、WP,它提供给应用程序开发者构建图形用户界面所需的所有功能。
虽然Qt在PC端大行其道,但是扩展到移动端,就显得乏力了,主要有如下几点原因:
第一:Qt 移动开发社区太小,学习资料不足,生态不好。
第二:官方推广不利,支持不够。
第三:移动端发力较晚,市场已被其它动态化框架占领( Hybrid 和 RN )。
第四:在移动开发中,C++ 开发和Web开发栈相比有着先天的劣势,直接结果就是 Qt 开发效率太低。
虽然Qt在移动端没有成功,但是它的理念被Flutter继承了,并使用更高级的语言来实现。
到了这里,你可能会问,自绘UI是个什么鬼?Flutter是如何实现统一的UI布局的?
Flutter 底层使用 Skia 作为其 2D 渲染引擎,Skia 是 Google的一个 2D 图形处理函数库,包含字型、坐标转换,以及点阵图,它们都有高效能且简洁的表现。Skia 是跨平台的,并提供了非常友好的 API,目前 Google Chrome浏览器和 Android 均采用 Skia 作为其 2D 绘图引擎。Skia 引擎会将使用 Dart 构建的抽象的视图结构数据加工成 GPU 数据,交由 OpenGL 最终提供给 GPU 渲染,至此完成渲染闭环,因此可以在最大程度上保证一款应用在不同平台、不同设备上的体验一致性。
当然除了UI外,其他的系统能力还需要针对不同的系统进行插件化处理,当然了Flutter会给你配置好的。
整个框架的架构如下:
自此,跨平台方案的三个时代的演进已经讲解完全,具体的优缺点对照如下:
我们在进行技术选型时,应该根据自身的项目复杂度、项目维护成本、社区活跃度、技术储备来进行对比选择。
综合比较,目前来说RN的活跃度是最高的,但是就技术前景来说,Flutter应该是后续发展的方向,我们应该本着学习新知识,新技术的目的去探索和玩转Flutter,毕竟学习是无止境的。