随着移动开发技术的火爆,flutter也是脱颖而出,一直想学习flutter,每次都是半途而废。2022已始,在此每周更新一篇文章来督促自己的学习。 本节将主要介绍一下移动开发技术的进化历程,了解一下 Flutter 技术出现的背景。在下认为,了解一门新技术出现的背景是非常重要的,因为只有了解之前是什么样的,才能理解为什么会是现在这样。
移动开发技术简介
原生开发
优势
- 可访问平台全部功能(GPS、摄像头);
- 速度快、性能高、可以实现复杂动画及绘制,整体用户体验好;
缺点
- 平台特定,开发成本高;不同平台必须维护不同代码,人力成本随之变大;
- 内容固定,动态化弱,大多数情况下,有新功能更新时只能发版; 在移动互联网发展初期,业务场景并不复杂,原生开发还可以应对产品需求迭代。 但近几年,随着物联网时代到来、移动互联网高歌猛进,日新月异,在很多业务场景中,传统的纯原生开发已经不能满足日益增长的业务需求。主要表现在:
- 动态化内容需求增大;当需求发生变化时,纯原生应用需要通过版本升级来更新内容,但应用上架、审核是需要周期的,这对高速变化的互联网时代来说是很难接受的,所以,对应用动态化(不发版也可以更新应用内容)的需求就变的迫在眉睫。
- 业务需求变化快,开发成本变大;由于原生开发一般都要维护Android、iOS两个开发团队,版本迭代时,无论人力成本,还是测试成本都会变大。
针对原生开发面临问题,业界一直都在努力寻找好的解决方案,而时至今日,已经有很多跨平台框架(注意,本书中所指的“跨平台”若无特殊说明,即特指 Android 和 iOS 两个平台),根据其原理,主要分为三类:
- H5 + 原生(Cordova、Ionic、微信小程序)
- JavaScript 开发 + 原生渲染 (React Native、Weex)
- 自绘UI + 原生 (Qt for mobile、Flutter)
H5 + 原生
这类框架主要原理就是将 App 中需要动态变动的内容通过HTML5(简称 H5)来实现,通过原生的网页加载控件WebView (Android)或 WKWebView(iOS)来加载(以后若无特殊说明,我们用WebView来统一指代 Android 和 iOS 中的网页加载控件)。这种方案中,H5 部分是可以随时改变而不用发版,动态化需求能满足;同时,由于 H5 代码只需要一次开发,就能同时在 Android 和 iOS 两个平台运行,这也可以减小开发成本,也就是说,H5 部分功能越多,开发成本就越小。我们称这种 H5 + 原生 的开发模式为混合开发 ,采用混合模式开发的App我们称之为混合应用或 HTMLybrid App ,如果一个应用的大多数功能都是 H5 实现的话,我们称其为 Web App 。
目前混合开发框架的典型代表有:Cordova、Ionic 。大多数 App 中都会有一些功能是 H5 开发的,至少目前为止,HTMLybrid App 仍然是最通用且最成熟的跨端解决方案。
在此,我们需要提一下小程序,目前国内各家公司小程序应用层的开发技术栈是 Web 技术栈,而底层渲染方式基本都是 WebView 和原生相结合的方式。
混合开发技术点
如之前所述,原生开发可以访问平台所有功能,而混合开发中,H5代码是运行在 WebView 中,而 WebView 实质上就是一个浏览器内核,其 JavaScript 依然运行在一个权限受限的沙箱中,所以对于大多数系统能力都没有访问权限,如无法访问文件系统、不能使用蓝牙等。所以,对于 H5 不能实现的功能,就需要原生去做了。
混合框架一般都会在原生代码中预先实现一些访问系统能力的 API , 然后暴露给 WebView 以供 JavaScript 调用。这样一来,WebView 中 JavaScript 与原生 API 之间就需要一个通信的桥梁,主要负责 JavaScript 与原生之间传递调用消息,而消息的传递必须遵守一个标准的协议,它规定了消息的格式与含义,我们把依赖于 WebView 的用于在 JavaScript 与原生之间通信并实现了某种消息传输协议的工具称之为 WebView JavaScript Bridge , 简称 JsBridge,它也是混合开发框架的核心。
总结
混合应用的优点是动态内容是 H5,Web 技术栈,社区及资源丰富,缺点是性能体验不佳,对于复杂用户界面或动画,WebView 有时会不堪重任。
JavaScript开发 + 原生渲染(React Native、Weex)
优点
- 采用 Web 开发技术栈,社区庞大、上手快、开发成本相对较低。
- 原生渲染,性能相比 H5 提高很多。
- 动态化较好,支持热更新。
缺点
- 渲染时需要 JavaScript 和原生之间通信,在有些场景如拖动可能会因为通信频繁导致卡顿。
- JavaScript 为脚本语言,执行时需要解释执行 (这种执行方式通常称为 JIT,即 Just In Time,指在执行时实时生成机器码),执行效率和编译类语言(编译类语言的执行方式为 AOT ,即 Ahead Of Time,指在代码执行前已经将源码进行了预处理,这种预处理通常情况下是将源码编译为机器码或某种中间码)仍有差距。
- 由于渲染依赖原生控件,不同平台的控件需要单独维护,并且当系统更新时,社区控件可能会滞后;除此之外,其控件系统也会受到原生UI系统限制,这就会导致,如果需要自定义原生渲染组件时,开发和维护成本过高
Qt Mobile
我们看看最后一种跨平台技术:自绘UI + 原生。这种技术的思路是:通过在不同平台实现一个统一接口的渲染引擎来绘制UI,而不依赖系统原生控件,所以可以做到不同平台UI的一致性。 注意,自绘引擎解决的是 UI 的跨平台问题,如果涉及其它系统能力调用,依然要涉及原生开发。
优点
- 性能高;由于自绘引擎是直接调用系统API来绘制UI,所以性能和原生控件接近。
- 灵活、组件库易维护、UI外观保真度和一致性高;由于UI渲染不依赖原生控件,也就不需要根据不同平台的控件单独维护一套组件库,所以代码容易维护。由于组件库是同一套代码、同一个渲染引擎,所以在不同平台,组件显示外观可以做到高保真和高一致性;另外,由于不依赖原生控件,也就不会受原生布局系统的限制,这样布局系统会非常灵活。
缺点
- 动态性不足;为了保证UI绘制性能,自绘UI系统一般都会采用 AOT 模式编译其发布包,所以应用发布后,不能像 Hybrid 和 RN 那些使用 JavaScript(JIT)作为开发语言的框架那样动态下发代码。
- 应用开发效率低:Qt 使用 C++ 作为其开发语言,而编程效率是直接会影响 App 开发效率的,C++ 作为一门静态语言,在 UI 开发方面灵活性不及 JavaScript 这样的动态语言,另外,C++需要开发者手动去管理内存分配,没有 JavaScript 及Java中垃圾回收(GC)的机制。 也许你已经猜到 Flutter 就属于这一类跨平台技术,没错,Flutter 正是实现一套自绘引擎,并拥有一套自己的 UI 布局系统,且同时在开发效率上有了很大突破。不过,自绘制引擎的思路并不是什么新概念,Flutter并不是第一个尝试这么做的,在它之前有一个典型的代表,即大名鼎鼎的Qt。
Flutter出世
Flutter 是 Google 发布的一个用于创建跨平台、高性能移动应用的框架。Flutter 和 Qt mobile 一样,都没有使用原生控件,相反都实现了一个自绘引擎,使用自身的布局、绘制系统。那么,我们会担心,Qt mobile 面对的问题Flutter是否也一样,Flutter会不会步入Qt mobile后尘,成为另一个烈士?要回到这个问题,我们先来看看Flutter诞生过程:从 2017 年 Google I/O 大会上,Google 首次发布 Flutter 到 2021年8月底,已经有 127K 的 Star,Star 数量 Github 上排名前 20 。经历了4年多的时间,Flutter 生态系统得以快速增长,国内外有非常多基于 Flutter 的成功案例,国内的互联网公司基本都有专门的 Flutter 团队。总之,历时 4 年,Flutter 发展飞快,已在业界得到了广泛的关注和认可,在开发者中受到了热烈的欢迎,成为了移动跨端开发中最受欢迎的框架之一。
现在,我们来和 Qt mobile做一个对比:
- 生态:Flutter 生态系统发展迅速,社区非常活跃,无论是开发者数量还是第三方组件都已经非常可观。
- 技术支持:现在 Google 正在大力推广Flutter,Flutter 的作者中很多人都是来自Chromium团队,并且 Github上活跃度很高。另一个角度,从 Flutter 诞生到现在,频繁的版本发布也可以看出 Google 对 Flutter的投入的资源不小,所以在官方技术支持这方面,大可不必担心。
- 开发效率:一套代码,多端运行;并且在开发过程中 Flutter 的热重载可帮助开发者快速地进行测试、构建UI、添加功能并更快地修复错误。在 iOS 和 Android 模拟器或真机上可以实现毫秒级热重载,并且不会丢失状态。这真的很棒,相信我,如果你是一名原生开发者,体验了Flutter开发流后,很可能就不想重新回去做原生了,毕竟很少有人不吐槽原生开发的编译速度。
基于以上三点,相信读者和笔者一样,已经迫不及待的想要去了解一下 Flutter 了。到现在为止,我们已经对移动端开发技术有了一个全面的了解,接下来我们便要进入本书的主题,你准备好了吗!