最近在学习Flutter,偶然发现 NiZerin 的这个系列的文章,写的非常好,于是决定一边阅读一边转载过来与大家一起分享学习,再次感谢 NiZerin 分享!
本来这一篇应该介绍如何搭建 Flutter 开发环境的,但我想在了解 Flutter 前,不妨了解一下跨平台技术的演进,这样更有助于学习 Flutter,也能认清 Flutter 的优势和本质。这篇文章还有一个目的,就是希望大家是玩技术的人,而不是被技术玩的人,对于不同的技术要有自己的判断。
我是 2010 年开始从事的 Android 开发,当时会 Android 和 iOS 开发的很少,也不火,所有人都在 “摸着河底过河”,项目更没有第三方框架一说,大都是自己写的,不像现在各种的框架满天飞。随着移动开发的发展,互联网公司也是层出不穷,有些公司迫于竞争,想要更迅速的更省成本的进行开发,就不再满足 Android 端一套代码,iOS 端一套代码。与此同时,其他技术领域和各大公司也都觊觎着这份大蛋糕,纷纷推出相关的技术,这样跨平台技术应运而生,并且开始在公司中生根发芽。
Android 和 iOS 生态太大了,我们可以把它们比作第一级生态,想要颠覆这两个系统的曾经出现过,但都失败了,因此建立次级生态是最稳妥的策略,Android 平台更加开放,因此次级生态的中心就是 Android,次生态的形式多种多样,比如在 Android 系统的基础上魔改建立自己的生态,再或者推出各种跨平台技术建立生态。跨平台技术产生的框架实在太多了,很多还没等我们去学去了解,它们就没落了,成为了跨平台技术的发展的一个过度产物。跨平台技术的产物是不靠谱还是趋势,我想读完本篇文章你会有自己的理解。
跨平台技术的分类没有标准的答案,这里把它们分类为 5 种,分别 Web App、Hybrid App、语言编译转换、原生渲染、自绘 UI。下面分别介绍它们。
Web App 是指基于 Web 的应用,运行于网络和标准浏览器上,相当于一个网页然后加一个 App 的壳。2014 年 HTML5 的标准规范制定完成,在网络舆论上 Web App 大有取代 Native App 的气势,但 Web App 有以下缺点,使得它始终是 “主角的心,配角的命” :
性能低,操作体验不好
无法调用原生 API,很多功能无法实现,
依赖于网络,网速慢时体验很差,并且没有离线功能,优化不好的话会消耗流量
只能做为一个临时的入口,用户留存率低
在 Web App 的基础上,又出现了几个进化者,这里主要介绍 PWA。
PWA(Progressive Web App)意为渐进式增强 Web 应用,它不是一门技术,而是一个概念,使用多种技术来增强 Web App 的功能:
用 Service Worker + HTTPS +Cache Api + indexedDB 等一系列 web 技术实现离线加载和缓存
实现了推送和通知
可以直接添加到手机的桌面上
使用 Service Worker 可以进行后台同步
总结起来,PWA 的主要的能力就是离线、推送、桌面访问,可以说 PWA 赋予 Web App 原生的体验,但是 PWA 一直不温不火的原因主要有以下几点:
游览器对 PWA 技术支持还不够全面, 不是每一款游览器都能 100% 的支持 PWA
国内一些手机厂商对 Android 系统各种魔改,对 PWA 的兼容性不好,甚至不支持 PWA
平台的竞争,iOS 对 PWA 的支持力度远远低于 Android,所以 PWA 在 iOS 上的体验打了折扣。PWA 面对类似的微信小程序和快应用的竞争中,并没有优势。
除了采用原生和 Web 开发 App,还可以采用 HTML5 + 原生来进行混合开发,这就是 Hybrid。
关于 Hybrid 的诞生有一个小故事,某个二线互联网公司的 App 是以原生为主,HTML5 开发打酱油,随着应用越来越复杂,终于有一天发现原生有一个方法最大数限制,一些页面需要内嵌 HTML5 的页面,于是原生和 HTML5 团队一起做了第一个 Hybrid 项目,这一套代码兼容三端并且效率很高,因此 Hybrid App 就成了这个公司的主流,业界其他的公司也都纷纷效仿。
原生 App 的架构图如下所示。
通过原生 SDK 提供的 API,App 可以与系统底层通信,以创建 UI 组件或访问系统服务。这些组件被渲染到手机屏幕,屏幕产生的相应的事件会被传回给组件。因为每个平台的系统组件是不同的,你需要为每个平台开发单独的 App,而 Hybrid App 不必这样,Hybrid App 的原生 UI 组件用来展示交互复杂和渲染要求高的界面,其他的可以交给 HTML5 来展示。
Hybrid App 虽然开发效率高,可以跨平台,但是 Hybrid 体验比不上原生,对于需要快速试错、快速占领市场的团队来说,Hybrid App 是一个不错的选择,后期团队稳定下来后,最好还是要做体验更好的原生 APP 或者使用其他体验更好的跨平台技术。
Hybrid 相关的技术有很多,比如 PhoneGap、Cordova、Ionic、VasSonic 等等,我们大概来了解一下。
说到 Cordova,不得不提到他的前身 PhoneGap,PhoneGap 面向 Web 开发人员,通过使用 HTML、CSS 和 Javascript 构建跨平台 App。2011 年,Apache 收购了 Nitobi Software 和它的 PhoneGap 产品,并对 PhoneGap 进行开源,PhoneGap 2.0 版本时,产品更名为 Apache Cordova。目前 Cordova 支持的平台有 Android、iOS、Windows、Mac OS X、Electron。
Cordova 的体系结构图如下所示。
Cordova 同样使用 WebView 来展示界面,插件是 Cordova 中不可或缺的一部分,Apache Cordova 维护了名为 Core Plugins 的插件,这些核心插件为 App 提供访问设备功能,如电池,相机,联系人等。除了核心插件之外,还有一些第三方插件可以使用,你也可以开发一个自己的插件。
Ionic Framework 是一个开源 UI 工具包,最早的目标是使用 HTML,CSS 和 JavaScript 等 Web 技术开发移动应用程序。由于 Web 技术的这一基础,Ionic 可以在网络运行的任何地方运行,比如 iOS,Android,浏览器,Electron,PWA 等等。
目前,Ionic Framework 已与 Angular 正式集成,但对 Vue 和 React 的支持正在开发中。
VasSonic 是由腾讯 VAS 团队开发的轻量级高性能混合框架,旨在加速在 Android 和 iOS 平台上运行的 H5 首屏。VasSonic 不仅支持服务器呈现的静态或动态网站,而且还完美兼容 Web 离线资源。VasSonic 使用自定义的 url 连接而不是原始网络连接来请求索引 html,因此它可以提前或并行请求资源以避免等待视图初始化。在这种并行的情况下,VasSonic 可以通过 WebKit 或 Blink 内核读取和呈现部分数据,而无需花费太多时间等待数据流的结束。
微信小程序的主要开发语言是 JavaScript ,小程序的开发同普通的网页开发相比有很大的相似性。
小程序的运行环境分成渲染层和逻辑层,这两层分别由 2 个线程管理,渲染层的界面使用了 WebView 进行渲染,逻辑层采用 JsCore 线程运行 JS 脚本。这两个线程的通信会经由微信客户端(Native)中的 JSBridage 做中转。逻辑层发送网络请求也经由 Native 转发,小程序的通信模型下图所示。
其中 WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。
微信小程序和 PWA 都是基于 Web 技术,原理的区别是小程序类似 Hybrid 架构,WebView 渲染基本的网页内容,对渲染性能要求较高的组件,通过原生组件来实现,比如相机、视频、地图等等,另外传统 Web 无法访问的本地能力,需要通过 JS SDK 来实现,而 PWA 则是使用多种技术增强 Web 能力,以达到接近 Native 应用的体验。
微信小程序本身和 App 就不是竞争关系,更多的是一个推广渠道,它更像是一张海报,用于快速推广倒流,而 App 则是要推广的对象。微信小程序的缺点很明显,体验上无法跟 App 相提并论,功能依托并受限于微信,无法进行拓展。可以说微信小程序就是建立了次级生态,这个生态中微信说的算,其他对手的发展会受到限制。
语言编译转换指的是直接将某个语言编译为一个平台下的二进制文件。比较有名的是 Xamarin 框架,虽然它在 Android 平台是内嵌了 Mono 虚拟机来实现的,但在 iOS 平台下是以 AOT 的方式编译为二进制文件的,所以把它归到语言编译转换类型。
Xamarin 始创于 2011 年,2016 年被微软正式收购。Xamarin 是 Mono 项目的一个分支,基于.NET 的跨平台实现的一个开源项目。
与 PhoneGap 等框架不同的是,Xamarin 可以在 iOS 和 Android 刚推出新的功能时,第一时间调用相应的 API,而使用 PhoneGap 则需要等待 PhoneGap 封装的新的功能后才可以调用相应的 API。
Xamarin 的 Andriod 实现原理如下图所示。
C# 代码写的 Andriod 应用在运行的在 Mono 虚拟机中,ART 可以通过 ACWs(Andriod Callable Wrappers)的方式执行到 Mono 中的 C# 代码。C# 代码要是想调用系统功能或者 Java 的实现类库,可以借助 MCW(Managed Callable Wrapper)的方式来实现。MCW 是 JNI 的桥梁,可以使用托管代码调用 Andriod 代码。
原生渲染在本篇文章中指的是由 JavaScript 开发并且由原生控件渲染,代表有 React Native、Weex、快应用。
Facebook 曾在移动端步履维艰,他们认为可以不借助任何原生开发手段来实现 Facebook 的移动应用,因此在早期选择了 HTML5,后来发现 HTML5 的效率始终无法和原生相比,因此在 2015 年发布了 React Native。
React Native 是 Facebook 早先开源的 Web UI 框架 React 在原生移动应用平台的衍生产物,底层对 Android 和 iOS 平台的原生代码进行封装,通过使用 JavaScript 就可以编写出原生代码。
Virtual DOM 是 DOM 在内存中的一种轻量级表达方式,可以通过不同的渲染引擎生成不同平台下的 UI。React Native 与原生框架通过 Bridge 进行通信,如果使用 Chrome 浏览器进行调试,那么所有的 JavaScript 代码将运行在 Chrome V8 引擎中,通过 WebSocket 和原生代码进行通信。
Weex 是阿里开源的一款跨平台移动开发工具,它能够完美兼顾性能与动态性,让移动开发者通过简捷的前端语法写出原生级别的性能体验,并支持 iOS、Android、YunOS 及 Web 等多端部署。目前 Vue.js 和 Rax 这两个前端框架被广泛应用于 Weex 页面开发,因此 Weex 支持 Vue 语法和 Rax 语法,而 React Native 只支持 JSX 语法。
Weex 首先将编写的 Weex 源码,通过 transformer 转换成 JS Bundle。然后将 JS Bundle 部署在服务器,当接收到终端(Android、Web 端、iOS 端)的 JS Bundle 请求时,将 JS Bundle 下发给终端。在终端中,由 Weex 的 JS Framework 接收和执行 JS Bundle 代码,并且执行数据绑定、模板编译等操作,然后输出 JSON 格式的 Virtual DOM,JS Framework 发送渲染指令给 Native ,提供 callNative 和 callJS 接口,方便 JS Framework 和 Native 的通信。
2018 年 3 月份,由小米,OPPO,VIVO,华为等 10 家国内主流厂商成立了快应用联盟。快应用介于移动网页和原生应用之间,第三方应用以移动网页的形式进行开发,最终得到原生渲染的效果体验。快应用框架深度集成进各手机厂商的手机操作系统中,可以在操作系统层面形成用户需求与应用服务的无缝连接,很多只用在原生应用中才能使用的功能,在快应用中可以很方便的实现,享受原生应用体验,同时不用担心分发留存等问题,资源消耗也比较少。对于每台手机设备,应用可以从多个系统入口,引用用户体验产品。
与 React Native 和 Weex 相比主要有两点不同:
快应用自身不支持 Vue 或 React 语法,它采用的是 JavaScript 开发。
React Native 和 Weex 的渲染引擎是集成到框架中的,每一个 APP 都需要打包一份,安装包体积较大,快应用渲染引擎是集成到 ROM 中的,应用中无需打包,安装包体积小。
和微信小程序很像,快应用本质上也是要建立次级生态,快应用的架构如下图所示。
快应用实现划分为编译时、运行时两个方面,UX 页面源码经过编译时得到 JS,然后经过运行时得到界面 UI。每一个页面由 HTML+CSS+JS 组成,编译运行后得到内存中的 DOM 树。多个页面组成一个项目,编译后得到 rpk 文件,最终运行时以应用形态呈现。
快应用推出 1 年后仍然不温不火,面对微信小程序,快应用在流量和入口等关键数据都无法与小程序匹敌,未来发展堪忧。
自绘 UI 指的是通过在不同平台实现一个统一接口的渲染引擎来绘制 UI,而不依赖系统平台的原生控件,这样做可以保证不同平台 UI 的一致性。不用像 React Native 一样,随着不同平台系统版本的变化,开发者还需要处理不同平台的差异,甚至有些特性只能在单个平台上实现,这样无法保证不同平台 UI 的一致性。自绘 UI 框架的代表有 Qt 和 Flutter。
Qt 产生的时间很早,Qt 第一版于 1991 年由 Trolltech 发布。后来在 2008 年,Nokia 斥资 1.5 亿美元收购 TrollTech,将 Qt 应用于 Symbian 程序开发。2012 年 8 月 9 日,Nokia 将 Qt 以 400 万欧元的价格出售给 Digia。2016 年 Qt Group Plc 从 Digia 分拆出来,2014 年 Qt 开始支持移动端的 Android、iOS、Wp 平台。虽然 Qt 在 PC 领域发展良好,但在移动端表现不佳,很少有人提及或者用 Qt 去开发移动端。
Flutter 是谷歌的移动 UI 框架,可以快速在 Android 和 iOS 上构建高质量的原生用户界面, 它的前身是谷歌试验项目 Sky。
Futter 提出了一切皆 Widget 的概念,除了基本的文本、图片、卡片、输入框,布局方式和动画等也都是由 Widget 组成的。通过使用不同类型的 Widget,就可以实现复杂度的界面。
Flutter 框架采用了分层设计,此设计的目标是帮助开发者使用更少的代码完成更多工作。例如,Material 层是由 widgets 层的普通 widget 组成的,而 widgets 层本身是通过来自 rendering 层的低级对象构建的。
目前在 Flutter 基础上开发的框架已经开始出现,这也证明了业界普遍开始认可 Flutter,并开始进行尝试。
跨平台技术的分类没有标准的答案,这里也只是粗略的进行分类,并对每个分类的主流框架进行介绍,实际上还有很多框架没有提到,它们不是没落了,就是缺点明显难以使用,再就是大公司的 KPI 产物。跨平台技术的演进好比百家争鸣,极大的促进了跨平台技术的发展。在我看来,这些技术让不同技术分支的程序员都可以参与到移动开发中,享受移动开发的乐趣,从这个角度来看这些跨平台技术的优劣之分是很难去评判的。我更希望有一个框架能统一整个跨平台技术,这个框架会是 Flutter 吗?还是下一个未知的框架?你更看好哪个跨平台技术呢?
————————————————
原文作者:NiZerin
转自链接:
https://learnku.com/articles/29481
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请保留以上作者信息和原文链接。