🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
本节内容转载于[Flutter中文网](https://flutterchina.club/) [TOC] # 原生开发 原生开发指开发某一个应用平台(如Android或iOS)所特有的应用,使用相应平台支持的开发工具和语言,并直接调用系统提供的SDK API。 原生开发的优势: * 可访问平台全部功能(GPS、摄像头) * 速度快、性能高、可实现复杂动画及绘制 * 用户体验好 原生开发缺点: * 平台特定,开发成本高,不同平台需要维护不同代码,人力成本随之增大 * 内容固定,动态化弱,新功能需发版才能更新 目前业务场景中的两个需求: 1、动态化内容需求增大 2、业务需求变化快,人力开发成本变大 针对这两个问题,诞生了一些跨平台的动态化框架。 # 跨平台开发 时至今日,已经有很多跨平台框架,根据其原理,主要分为三类: * H5+原生混合开发(Cordova、Ionic、微信小程序) * JavaScript开发+原生渲染 (React Native、Weex、快应用) * 自绘UI+原生(QT for mobile、Flutter) ## H5+原生混合开发 框架:Cordova、Ionic、微信小程序等 混合开发的原理是将APP的一部分需要动态变动的内容通过H5来实现,通过原生的网页加载控件WebView (Android)或WKWebView(iOS)来加载。H5部分是可以随时改变而不用发版,动态化需求能满足;同时由于H5代码只需要一次开发,就能同时在Android和iOS两个平台运行,可以减小开发成本。 混合开发中H5代码运行在WebView中,而WebView本质是一个浏览器内核,其JavaScript运行在一个权限受限的沙箱中,所以对于大多数系统能力没有访问权限,如无法访问文件系统、不能使用蓝牙等。 对于H5不能实现的功能,都需要原生去做。混合框架一般都会在原生代码中预先实现一些访问系统能力的API, 暴露给WebView以供JavaScript调用。 WebView就成了JavaScript与原生API之间通信的桥梁,主要负责JavaScript与原生之间传递调用消息。消息的传递必须遵守一个标准的协议,来规定消息的格式与含义,我们把依赖于WebView的用于在JavaScript与原生之间通信并实现了某种消息传输协议的工具称之为**WebView JavaScript Bridge**, 简称**JsBridge**,JsBridge是混合开发框架的核心。 ### 优点与缺点 优点: 1、H5加载,可以实现动态化,无需发版即可更新内容 2、一套代码开发,开发成本低 缺点: 1、性能不好,无法高效渲染复杂的用户界面或动画 2、无法直接访问部分系统能力(如文件系统、蓝牙等) ## JavaScript开发+原生渲染 框架:Reactive Native、Weex及快应用 ### 响应式编程 React中有一个重要思想:状态改变则UI随之自动改变。React框架的工作就是响应用户状态改变的事件,重新构建用户界面,React是典型的**响应式**编程。 React中响应式原理如下: * 1、开发者只需关注状态转移,当状态发生变化时,React框架会自动根据新的状态重新构建UI。 * 2、React框架在接收到用户状态改变的通知后,根据当前渲染树,结合最新的状态改变,通过Diff算法,计算出树中变化的部分,然后只更新变化的部分(DOM操作),从而避免整棵树重构,提高性能。 需要注意的是,第二步中状态变化后,React框架并不会立即去计算并渲染DOM树的变化部分。相反,React会在DOM的基础上建立一个抽象层,即**虚拟DOM**树,对数据和状态所做的任何改动,都会被自动且高效的同步到虚拟DOM,最后再批量同步到真实DOM中,而不是每次改变都去操作一下DOM。因为在浏览器中每一次DOM操作都有可能引起浏览器的重绘或回流,浏览器的重绘和回流都是比较昂贵的操作,如每一次改变都直接对DOM进行操作,会带来性能问题,而批量操作只会触发一次DOM更新。 ### Reactive Native原理 Reactive Native是React在原生移动应用平台的衍生产物,两者的主要区别在于:React中虚拟DOM最终会映射为浏览器DOM树,而Reactive Native中虚拟DOM会通过JavaScripCore映射为原生控件树。 JavaScriptCore是一个JavaScript解释器,在ReactiveNative中主要有两个作用: * 为JavaScript提供运行环境 * 是JavaScript与原生应用间的通信桥梁,作用和JsBridge一样(在iOS中,很多JsBridge的实现都是基于JavaScriptCore) 在ReactiveNative中将虚拟DOM映射称为原生控件需要两步: * 布局消息传递: 将虚拟DOM布局信息传递给原生 * 原生根据布局信息通过对应的原生控件渲染控件树 ### Weex与快应用 Weex思想及原理与ReactiveNative类似,不同的是语法层面,Weex支持Vue语法和Rax语法。 快应用是华为、小米、OPPO、魅族等国内9大主流手机厂商共同制定的轻量级应用标准,目标直指微信小程序,它也是采用JavaScript语言开发,原生控件渲染,与React Native和Weex相比主要有两点不同: * 快应用自身不支持Vue或React语法,其采用原生JavaScript开发(开发框架和微信小程序很像,值得一提的是小程序目前已经可以使用Vue语法开发(mpvue)) * React Native和Weex的渲染/排版引擎是集成到框架中的,每一个APP都需要打包一份,安装包体积较大;而快应用渲染/排版引擎是集成到ROM中的,应用中无需打包,安装包体积小,正因如此,快应用才能在保证性能的同时做到快速分发。 ### 优点与缺点 优点: 1、原生控件渲染,性能比混合应用中的H5提高很多 2、使用Web开发技术栈,只需要维护一份代码,开发成本相对较低 3、动态化较好,支持热更新 缺点: 1、渲染时需要JavaScript与原生之间进行通信,某些场景可能因通信频繁导致卡顿 2、JavaScript为脚本语言,执行时需要JIT(Just In Time),执行效率和AOT(Ahead Of Time)代码仍有差距 3、渲染依赖原生控件,不同平台控件需要单独维护,系统更新时,社区控件可能会滞后。除此之外,控件系统也会受到原生UI系统限制,比如解决手势冲突问题。 ## 自绘UI+原生 通过在不同平台实现一个统一接口的渲染引擎来绘制UI,而不依赖系统原生控件,所以可以做到不同平台UI的一致性。自绘引擎解决的是UI的跨平台问题,涉及其它系统能力调用,依然要使用原生开发。 ### 优点与缺点 优点: 1、直接调用系统API来绘制UI,性能好 2、UI渲染不依赖原生控件,不需要根据不同平台的控件单独维护一套组件库,代码易维护 3、组件库是同一套代码、同一个渲染引擎,在不同平台组件上,显示外观可以做到高保真和高一致性; 4、不依赖原生控件,布局系统更加灵活 缺点: 动态性不足,自绘UI系统一般采用AOT模式编译其发布包,不能像使用JIT开发语言框架那样动态下发代码 ### QT Mobile 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没有流行起来的原因所在: * QT移动开发社区太小,学习资料不足,生态不好 * 官方推广不利,支持不够 * 移动端发力较晚,市场已被其它动态化框架占领(Hybrid和RN) * 在移动开发中,C++开发和Web开发栈相比有着先天的劣势,直接结果就是QT开发效率太低 ### Flutter Flutter是Google发布的一个用于创建跨平台、高性能移动应用的框架。Flutter和QT mobile一样,都没有使用原生控件,相反都实现了一个自绘引擎,使用自身的布局、绘制系统。 ## 总结 | 技术类型 | UI渲染方式 | 性能 | 开发效率 | 动态化 | 框架代表 | | --- | --- | --- | --- | --- | --- | | H5+原生 | WebView渲染 | 一般 | 高 | 支持 | Cordova、Ionic | | JavaScript+原生渲染 | 原生控件渲染 | 好 | 中 | 支持 | RN、Weex | | 自绘UI+原生 | 调用系统API渲染 | 好 | Flutter高, QT低 | 默认不支持 | QT、Flutter | Flutter的Release包默认是使用Dart AOT模式编译的,所以不支持动态化,但Dart还有JIT或snapshot运行方式,这些模式都是支持动态化的。