@nextleaf
2019-04-07T02:27:56.000000Z
字数 6066
阅读 1601
移动应用
跨平台
混和开发
Flutter
移动应用跨平台开发框架,根据其原理,主要分为三类:
这类框架主要原理就是将APP的一部分需要动态变动的内容通过H5来实现,通过原生的网页加载控件WebView (Android)或WKWebView(ios)来加载(以后若无特殊说明,用WebView来统一指代android和ios中的网页加载控件)。这样一来,H5部分是可以随时改变而不用发版,动态化需求能满足;同时,由于h5代码只需要一次开发,就能同时在Android和iOS两个平台运行,这也可以减小开发成本,也就是说,h5部分功能越多,开发成本就越小。我们称这种h5+原生的开发模式为混合开发 ,采用混合模式开发的APP我们称之为混合应用或Hybrid APP ,如果一个应用的大多数功能都是H5实现的话,我们称其为Web APP 。
目前混合开发框架的典型代表有:Cordova、Ionic 和微信小程序,值得一提的是微信小程序目前是在webview中渲染的,并非原生渲染,但将来有可能会采用原生渲染。
原生开发可以访问平台所有功能,而混合开发中,h5代码是运行在WebView中,而WebView实质上就是一个浏览器内核,其JavaScript依然运行在一个权限受限的沙箱中,所以对于大多数系统能力都没有访问权限,如无法访问文件系统、不能使用蓝牙等。所以,对于H5不能实现的功能,都需要原生去做。而混合框架一般都会在原生代码中预先实现一些访问系统能力的API, 然后暴露给WebView以供JavaScript调用,这样一来,WebView就成为了JavaScript与原生API之间通信的桥梁,主要负责JavaScript与原生之间传递调用消息,而消息的传递必须遵守一个标准的协议,它规定了消息的格式与含义,我们把依赖于WebView的用于在JavaScript与原生之间通信并实现了某种消息传输协议的工具称之为WebView JavaScript Bridge, 简称 JsBridge,它也是混合开发框架的核心。
混合应用的优点是动态内容是H5,web技术栈,社区及资源丰富,缺点是性能不好,对于复杂用户界面或动画,webview不堪重任。
React Native (简称RN)是Facebook于2015年4月开源的跨平台移动应用开发框架,是Facebook早先开源的JS框架 React 在原生移动应用平台的衍生产物,目前支持iOS和Android两个平台。RN使用Javascript语言,类似于HTML的JSX,以及CSS来开发移动应用,因此熟悉Web前端开发的技术人员只需很少的学习就可以进入移动应用开发领域。
由于RN和React原理相通,并且Flutter也是受React启发,很多思想也都是相通的,万丈高楼平地起,我们有必要深入了解一下React原理。React是一个响应式的Web框架,我们先了解一下两个重要的概念:Dom树与响应式编程。
文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标志语言的标准编程接口,一种独立于平台和语言的方式访问和修改一个文档的内容和结构。换句话说,这是表示和处理一个HTML或XML文档的标准接口。简单来说,DOM就是文档树,与用户界面控件树对应,在前端开发中通常指HTML对应的渲染树,但广义的DOM也可以指Android中的XML布局文件对应的控件树,而术语DOM操作就是指直接来操作渲染树(或控件树), 因此,可以看到其实DOM树和控件树是等价的概念,只不过前者常用语Web开发中,而后者常用于原生开发中。
React中提出一个重要思想:状态改变则UI随之自动改变,而React框架本身就是响应用户状态改变的事件而执行重新构建用户界面的工作,这就是典型的响应式编程范式,下面我们总结一下React中响应式原理:
开发者只需关注状态转移(数据),当状态发生变化,React框架会自动根据新的状态重新构建UI。
React框架在接收到用户状态改变通知后,会根据当前渲染树,结合最新的状态改变,通过Diff算法,计算出树中变化的部分,然后只更新变化的部分(DOM操作),从而避免整棵树重构,提高性能。
值得注意的是,在第二步中,状态变化后React框架并不会立即去计算并渲染DOM树的变化部分,相反,React会在DOM的基础上建立一个抽象层,即虚拟DOM树,对数据和状态所做的任何改动,都会被自动且高效的同步到虚拟DOM,最后再批量同步到真实DOM中,而不是每次改变都去操作一下DOM。为什么不能每次改变都直接去操作DOM树?这是因为在浏览器中每一次DOM操作都有可能引起浏览器的重绘或回流:
如果DOM只是外观风格发生变化,如颜色变化,会导致浏览器重绘界面。
如果DOM树的结构发生变化,如尺寸、布局、节点隐藏等导致,浏览器就需要回流(及重新排版布局)。
而浏览器的重绘和回流都是比较昂贵的操作,如果每一次改变都直接对DOM进行操作,这会带来性能问题,而批量操作只会触发一次DOM更新。
思考题:Diff操作和DOM批量更新难道不应该是浏览器的职责吗?第三方框架中去做合不合适?
上文已经提到React Native 是React 在原生移动应用平台的衍生产物,那两者主要的区别是什么呢?其实,主要的区别在于虚拟DOM映射的对象是什么。React中虚拟DOM最终会映射为浏览器DOM树,而RN中虚拟DOM会通过 JavaScriptCore 映射为原生控件树。
JavaScriptCore 是一个JavaScript解释器,它在React Native中主要有两个作用:
而RN中将虚拟DOM映射为原生控件的过程中分两步:
原生根据布局信息通过对应的原生控件渲染控件树;
至此,React Native 便实现了跨平台。 相对于混合应用,由于React Native是原生控件渲染,所以性能会比混合应用中H5好很多,同时React Native是Web开发技术栈,也只需维护一份代码,同样是跨平台框架。
Weex是阿里巴巴于2016年发布的跨平台移动端开发框架,思想及原理和React Native类似,最大的不同是语法层面,Weex支持Vue语法和Rax语法,Rax 的 DSL 语法是基于 React JSX 语法而创造。与 React 不同,在 Rax 中 JSX 是必选的,它不支持通过其它方式创建组件,所以学习 JSX 是使用 Rax 的必要基础。而React Native只支持JSX语法。
快应用是华为、小米、OPPO、魅族等国内9大主流手机厂商共同制定的轻量级应用标准,目标直指微信小程序。它也是采用JavaScript语言开发,原生控件渲染,与React Native和Weex相比主要有两点不同:
JavaScript开发+原生渲染的方式主要优点如下:
不足:
在本篇中,我们看看最后一种跨平台技术:自绘UI+原生。这种技术的思路是,通过在不同平台实现一个统一接口的渲染引擎来绘制UI,而不依赖系统原生控件,所以可以做到不同平台UI的一致性。注意,自绘引擎解决的是UI的跨平台问题,如果涉及其它系统能力调用,依然要涉及原生开发。这种平台技术的优点如下:
不足:
Flutter正是实现一套自绘引擎,并拥有一套自己的UI布局系统。不过,自绘制引擎的思路并不是什么新概念,Flutter并不是第一个尝试这么做的,在它之前有一个典型的代表,即大名鼎鼎的QT。
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的声音,但一直很弱,无论QT本身技术如何、设计思想如何,但事实上终究是败了,究其原因,笔者认为主要有四:
第一:QT移动开发社区太小,学习资料不足,生态不好。
第二:官方推广不利,支持不够。
第三:移动端发力较晚,市场已被其它动态化框架占领(Hybrid和RN)。
第四:在移动开发中,C++开发和Web开发栈相比有着先天的劣势,直接结果就是QT开发效率太低。
基于此四点,尽管QT是移动端开发跨平台自绘引擎的先驱,但却成为了烈士。
Flutter是Google发布的一个用于创建跨平台、高性能移动应用的框架。Flutter和QT mobile一样,都没有使用原生控件,相反都实现了一个自绘引擎,使用自身的布局、绘制系统。那么,我们会担心,QT mobile面对的问题Flutter是否也一样,Flutter会不会步入QT mobile后尘,成为另一个烈士?要回到这个问题,我们先来看看Flutter诞生过程:
2017 年 Google I/O 大会上,Google 首次推出了一款新的用于创建跨平台、高性能的移动应用框架——Flutter。
2018年2月,Flutter发布了第一个Beta版本,同年五月, 在2018年Google I/O 大会上,Flutter 更新到了 beta 3 版本。
2018年6月,Flutter发布了首个预览版本,这意味着 Flutter 进入了正式版(1.0)发布前的最后阶段。
观其发展,在2018年5月份,Flutter 进入了 GitHub stars 排行榜前 100 名,已有 27k star。而今天(2018年8月16日),已经有35K的Star。经历了短短一年多的时间,Flutter 生态系统得以快速增长,由此可见,Flutter在开发者中受到了热烈的欢迎,其未来发展值得期待!
现在,我们来和QT mobile做一个对比:
目前移动开发中三种跨平台技术对比:
技术类型 | UI渲染方式 | 性能 | 开发效率 | 动态化 | 框架代表 |
---|---|---|---|---|---|
H5+原生 | WebView渲染 | 一般 | 高 | ✔️ | Cordova、Ionic |
JavaScript+原生渲染 | 原生控件渲染 | 好 | 高 | ✔️ | RN、Weex |
自绘UI+原生 | 调用系统API渲染 | 好 | Flutter高, QT低 | 默认不支持 | QT、Flutter |
上表中开发语言主要指UI的开发语言,动态化主要指是否支持动态下发代码和是否支持热更新。值得注意的是Flutter的Release包默认是使用Dart AOT模式编译的,所以不支持动态化,但Dart还有JIT或snapshot运行方式,这些模式都是支持动态化的,后续会介绍
整理自https://book.flutterchina.club/chapter1/mobile_development_intro.html