本文首发于微信公众号「后厂技术官」

关联系列
ReactNative入门系列
React Native组件

本文首发于公众号「刘望舒」

前言

本来这一篇应该介绍如何搭建Flutter开发环境的,但我想在了解Flutter前,不妨了解一下跨平台技术的演进,这样更有助于学习Flutter,也能认清Flutter的优势和本质。这篇文章还有一个目的,就是希望大家是玩技术的人,而不是被技术玩的人,对于不同的技术要有自己的判断。

1. 跨平台技术的诞生

我是2010年开始从事的Android开发,当时会Android和iOS开发的很少,也不火,所有人都在“摸着河底过河”,项目更没有第三方框架一说,大都是自己写的,不像现在各种的框架满天飞。随着移动开发的发展,互联网公司也是层出不穷,有些公司迫于竞争,想要更迅速的更省成本的进行开发,就不再满足Android端一套代码,iOS端一套代码。与此同时,其他技术领域和各大公司也都觊觎着这份大蛋糕,纷纷推出相关的技术,这样跨平台技术应运而生,并且开始在公司中生根发芽。
Android和iOS生态太大了,我们可以把它们比作第一级生态,想要颠覆这两个系统的曾经出现过,但都失败了,因此建立次级生态是最稳妥的策略,Android平台更加开放,因此次级生态的中心就是Android,次生态的形式多种多样,比如在Android系统的基础上魔改建立自己的生态,再或者推出各种跨平台技术建立生态。跨平台技术产生的框架实在太多了,很多还没等我们去学去了解,它们就没落了,成为了跨平台技术的发展的一个过度产物。跨平台技术的产物是不靠谱还是趋势,我想读完本篇文章你会有自己的理解。
跨平台技术的分类没有标准的答案,这里把它们分类为5种,分别Web App、Hybrid App、语言编译转换、原生渲染、自绘UI。下面分别介绍它们。

2. Web App

Web App是指基于Web的应用,运行于网络和标准浏览器上,相当于一个网页然后加一个App的壳。2014年HTML5的标准规范制定完成,在网络舆论上Web App大有取代Native App的气势,但Web App有以下缺点,使得它始终是“主角的心,配角的命” :

  • 性能低,操作体验不好
  • 无法调用原生API,很多功能无法实现,
  • 依赖于网络,网速慢时体验很差,并且没有离线功能,优化不好的话会消耗流量
  • 只能做为一个临时的入口,用户留存率低

在Web App的基础上,又出现了几个进化者,这里主要介绍PWA。

2.1 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面对类似的微信小程序和快应用的竞争中,并没有优势。

3. Hybrid App

除了采用原生和Web开发App,还可以采用HTML5+原生来进行混合开发,这就是Hybrid。
关于Hybrid的诞生有一个小故事,某个二线互联网公司的App是以原生为主,HTML5开发打酱油,随着应用越来越复杂,终于有一天发现原生有一个方法最大数限制,一些页面需要内嵌HTML5的页面,于是原生和HTML5团队一起做了第一个Hybrid项目,这一套代码兼容三端并且效率很高,因此Hybrid App就成了这个公司的主流,业界其他的公司也都纷纷效仿。

原生App的架构图如下所示。
VZ9wQI.png

通过原生SDK提供的API,App可以与系统底层通信,以创建 UI 组件或访问系统服务。这些组件被渲染到手机屏幕,屏幕产生的相应的事件会被传回给组件。因为每个平台的系统组件是不同的,你需要为每个平台开发单独的 App,而Hybrid App不必这样,Hybrid App的原生UI组件用来展示交互复杂和渲染要求高的界面,其他的可以交给HTML5来展示。
Hybrid App虽然开发效率高,可以跨平台,但是Hybrid体验比不上原生,对于需要快速试错、快速占领市场的团队来说,Hybrid App是一个不错的选择,后期团队稳定下来后,最好还是要做体验更好的原生APP或者使用其他体验更好的跨平台技术。

Hybrid相关的技术有很多,比如PhoneGap、Cordova、Ionic、VasSonic等等,我们大概来了解一下。

3.1 Cordova

说到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的体系结构图如下所示。
VZ90yt.png

Cordova同样使用WebView来展示界面,插件是Cordova中不可或缺的一部分,Apache Cordova维护了名为Core Plugins的插件,这些核心插件为App提供访问设备功能,如电池,相机,联系人等。除了核心插件之外,还有一些第三方插件可以使用,你也可以开发一个自己的插件。

3.2 Ionic

Ionic Framework是一个开源UI工具包,最早的目标是使用HTML,CSS和JavaScript等Web技术开发移动应用程序。由于Web技术的这一基础,Ionic可以在网络运行的任何地方运行,比如 iOS,Android,浏览器,Electron,PWA等等。
目前,Ionic Framework已与Angular正式集成,但对Vue和React的支持正在开发中。

3.3 VasSonic

VasSonic是由腾讯VAS团队开发的轻量级高性能混合框架,旨在加速在Android和iOS平台上运行的H5首屏。VasSonic不仅支持服务器呈现的静态或动态网站,而且还完美兼容Web离线资源。VasSonic使用自定义的url连接而不是原始网络连接来请求索引html,因此它可以提前或并行请求资源以避免等待视图初始化。在这种并行的情况下,VasSonic可以通过WebKit或Blink内核读取和呈现部分数据,而无需花费太多时间等待数据流的结束。

3.4 微信小程序

​微信小程序的主要开发语言是 JavaScript ,小程序的开发同普通的网页开发相比有很大的相似性。
小程序的运行环境分成渲染层和逻辑层,这两层分别由2个线程管理,渲染层的界面使用了WebView 进行渲染,逻辑层采用JsCore线程运行JS脚本。这两个线程的通信会经由微信客户端(Native)中的JSBridage做中转。逻辑层发送网络请求也经由Native转发,小程序的通信模型下图所示。
VZ9ref.png

其中 WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。
微信小程序和PWA都是基于Web技术,原理的区别是小程序类似Hybrid架构,WebView渲染基本的网页内容,对渲染性能要求较高的组件,通过原生组件来实现,比如相机、视频、地图等等,另外传统Web无法访问的本地能力,需要通过JS SDK来实现,而PWA则是使用多种技术增强Web能力,以达到接近Native应用的体验。

微信小程序本身和App就不是竞争关系,更多的是一个推广渠道,它更像是一张海报,用于快速推广倒流,而App则是要推广的对象。微信小程序的缺点很明显,体验上无法跟App相提并论,功能依托并受限于微信,无法进行拓展。可以说微信小程序就是建立了次级生态,这个生态中微信说的算,其他对手的发展会受到限制。

4. 语言编译转换

语言编译转换指的是直接将某个语言编译为一个平台下的二进制文件。比较有名的是Xamarin框架,虽然它在 Android平台是内嵌了Mono虚拟机来实现的,但在 iOS平台下是以AOT 的方式编译为二进制文件的,所以把它归到语言编译转换类型。

4.1 Xamarin

Xamarin始创于2011年,2016年被微软正式收购。Xamarin是Mono项目的一个分支,基于.NET的跨平台实现的一个开源项目。
与PhoneGap等框架不同的是,Xamarin可以在iOS和Android刚推出新的功能时,第一时间调用相应的API,而使用PhoneGap则需要等待PhoneGap封装的新的功能后才可以调用相应的API。
Xamarin的Andriod实现原理如下图所示。
VZ9UWd.png
 C#代码写的Andriod应用在运行的在Mono虚拟机中,ART可以通过ACWs(Andriod Callable Wrappers)的方式执行到Mono中的C#代码。C#代码要是想调用系统功能或者Java的实现类库,可以借助MCW(Managed Callable Wrapper)的方式来实现。MCW是JNI的桥梁,可以使用托管代码调用Andriod代码。

5. 原生渲染

原生渲染在本篇文章中指的是由JavaScript开发并且由原生控件渲染,代表有React Native、Weex、快应用。

5.1 React Native

Facebook曾在移动端步履维艰,他们认为可以不借助任何原生开发手段来实现Facebook的移动应用,因此在早期选择了HTML5,后来发现HTML5的效率始终无法和原生相比,因此在2015年发布了React Native。
React Native是Facebook早先开源的 Web UI框架React在原生移动应用平台的衍生产物,底层对Android和iOS平台的原生代码进行封装,通过使用JavaScript就可以编写出原生代码。
VZ9tFe.png
Virtual DOM是DOM在内存中的一种轻量级表达方式,可以通过不同的渲染引擎生成不同平台下的UI。React Native与原生框架通过Bridge进行通信,如果使用Chrome浏览器进行调试,那么所有的JavaScript代码将运行在Chrome V8引擎中,通过WebSocket和原生代码进行通信。

5.2 Weex

Weex 是阿里开源的一款跨平台移动开发工具,它能够完美兼顾性能与动态性,让移动开发者通过简捷的前端语法写出原生级别的性能体验,并支持iOS、Android、YunOS及Web等多端部署。目前 Vue.js 和 Rax 这两个前端框架被广泛应用于 Weex 页面开发,因此Weex支持Vue语法和Rax语法,而React Native只支持JSX语法。

VZ9yTS.jpg
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 的通信。

5.3 快应用

2018年3月份,由小米,OPPO,VIVO,华为等10家国内主流厂商成立了快应用联盟。快应用介于移动网页和原生应用之间,第三方应用以移动网页的形式进行开发,最终得到原生渲染的效果体验。快应用框架深度集成进各手机厂商的手机操作系统中,可以在操作系统层面形成用户需求与应用服务的无缝连接,很多只用在原生应用中才能使用的功能,在快应用中可以很方便的实现,享受原生应用体验,同时不用担心分发留存等问题,资源消耗也比较少。对于每台手机设备,应用可以从多个系统入口,引用用户体验产品。
与React Native和Weex相比主要有两点不同:

  • 快应用自身不支持Vue或React语法,它采用的是JavaScript开发。
  • React Native和Weex的渲染引擎是集成到框架中的,每一个APP都需要打包一份,安装包体积较大,快应用渲染引擎是集成到ROM中的,应用中无需打包,安装包体积小。

和微信小程序很像,快应用本质上也是要建立次级生态,快应用的架构如下图所示。
VZ92Wj.png

快应用实现划分为编译时、运行时两个方面,UX页面源码经过编译时得到JS,然后经过运行时得到界面UI。每一个页面由HTML+CSS+JS组成,编译运行后得到内存中的DOM树。多个页面组成一个项目,编译后得到rpk文件,最终运行时以应用形态呈现。

快应用推出1年后仍然不温不火,面对微信小程序,快应用在流量和入口等关键数据都无法与小程序匹敌,未来发展堪忧。

6. 自绘UI

自绘UI指的是通过在不同平台实现一个统一接口的渲染引擎来绘制UI,而不依赖系统平台的原生控件,这样做可以保证不同平台UI的一致性。不用像React Native一样,随着不同平台系统版本的变化,开发者还需要处理不同平台的差异,甚至有些特性只能在单个平台上实现,这样无法保证不同平台UI的一致性。自绘UI框架的代表有Qt和Flutter。

6.1 Qt

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去开发移动端。

6.2 Flutter

Flutter是谷歌的移动UI框架,可以快速在Android和iOS上构建高质量的原生用户界面, 它的前身是谷歌试验项目Sky。
Futter提出了一切皆Widget的概念,除了基本的文本、图片、卡片、输入框,布局方式和动画等也都是由Widget组成的。通过使用不同类型的Widget,就可以实现复杂度的界面。
VZ9cFg.png

Flutter框架采用了分层设计,此设计的目标是帮助开发者使用更少的代码完成更多工作。例如,Material层是由widgets层的普通widget组成的,而widgets层本身是通过来自rendering层的低级对象构建的。
目前在Flutter基础上开发的框架已经开始出现,这也证明了业界普遍开始认可Flutter,并开始进行尝试。

总结

跨平台技术的分类没有标准的答案,这里也只是粗略的进行分类,并对每个分类的主流框架进行介绍,实际上还有很多框架没有提到,它们不是没落了,就是缺点明显难以使用,再就是大公司的KPI产物。跨平台技术的演进好比百家争鸣,极大的促进了跨平台技术的发展。在我看来,这些技术让不同技术分支的程序员都可以参与到移动开发中,享受移动开发的乐趣,从这个角度来看这些跨平台技术的优劣之分是很难去评判的。我更希望有一个框架能统一整个跨平台技术,这个框架会是Flutter吗?还是下一个未知的框架?你更看好哪个跨平台技术呢?

感谢
https://visualstudio.microsoft.com/xamarin/
https://phonegap.com/
https://cordova.apache.org/
https://github.com/Tencent/VasSonic
https://book.flutterchina.club/chapter1/mobile_development_intro.html
https://developers.weixin.qq.com/miniprogram/dev/quickstart/basic/framework.html
https://docs.microsoft.com/zh-cn/xamarin/android/platform/binding-java-library/
https://blog.csdn.net/baidu_browser/article/details/64440238
http://fex.baidu.com/blog/2015/05/cross-mobile/
https://www.cnblogs.com/yexiaochai/p/4921635.html
https://www.infoq.cn/article/why-is-flutter-revolutionary
https://blog.csdn.net/MeituanTech/article/details/81567238
http://www.uml.org.cn/AJAX/201812283.asp
https://blog.csdn.net/powertoolsteam/article/details/51496229
https://www.jianshu.com/p/32285c709682
https://www.jianshu.com/p/098af61bbe04
https://segmentfault.com/a/1190000012353473?utm_source=tag-newest
https://www.uisdc.com/web-hybrid-native-app
https://www.jianshu.com/p/7e0bd4708ba7