针对原生开发面临的问题,业界一直都在努力寻找好的解决方案,而时至今日,已经有很多跨平台框架(注意,本书中所指的“跨平台”若无特殊说明,即特指 Android 和 iOS 两个平台),根据其原理,主要分为三类:
hybrid :H5 + 原生(Cordova、Ionic、微信小程序)
JavaScript 开发 + 原生渲染 (React Native、Weex)
自绘UI + 原生 (Qt for mobile、Flutter)
1、Hybrid :H5 + 原生
主要原理:
将 App 中需要动态变动的内容通过HTML5(简称 H5)来实现,
通过原生的网页加载控件WebView (Android)或 WKWebView(iOS)来加载。
WebView 中 JavaScript 与原生 API 之间就需要一个通信的桥梁,JsBridge。
优点是:动态内容可以用 H5开发,而H5是Web 技术栈,Web技术栈生态开放且社区资源丰富,整体开发效率高。
缺点是:
1.性能体验不佳,对于复杂用户界面或动画,WebView 有时会不堪重任。
2.其 JavaScript 依然运行在一个权限受限的沙箱中,所以对于大多数系统能力都没有访问权限,如无法访问文件系统、不能使用蓝牙等。所以,对于 H5 不能实现的功能,就需要原生去做了。
2、JavaScript开发 + 原生渲染 (React Native、Weex)
2.1、React Native
1.React Native (简称 RN )是 Facebook 开源的跨平台移动应用开发框架。
目前支持 iOS 和 Android 两个平台。
2.React Native 基于 JavaScript,开发者可以利用已有的前端开发经验快速上手
3.开发者编写的js代码,通过 react native 的中间层转化为原生控件和操作
4.react native 运行在JavaCore中,所以不存在浏览器兼容的问题
最终,JS代码会被打包成一个 bundle 文件,自动添加到 App 的资源目录下。
JavaScriptCore 是一个JavaScript解释器,它在React Native中主要有两个作用:
- 为 JavaScript 提供运行环境。
- 是 JavaScript 与原生应用之间通信的桥梁,作用和 JsBridge 一样,事实上,在 iOS 中,很多 JsBridge 的实现都是基于 JavaScriptCore 。
而 RN 中将虚拟 DOM 映射为原生控件的过程主要分两步:
- 布局消息传递; 将虚拟 DOM 布局信息传递给原生;
- 原生根据布局信息通过对应的原生控件渲染;
RN 和 React 原理相通,React 是一个响应式的 Web 框架。详细原理参考:
原理
- 开发者只需关注状态转移(数据),当状态发生变化,React 框架会自动根据新的状态重新构建UI。
- React 框架在接收到用户状态改变通知后,会根据当前渲染树,结合最新的状态改变,通过 Diff 算法,计算出树中变化的部分,然后只更新变化的部分(DOM操作),从而避免整棵树重构,提高性能
2.2、Weex
1.Weex 是阿里的跨平台移动端开发框架,思想及原理和 React Native 类似
底层都是通过原生渲染的
2.不同是应用层开发语法 (即 DSL,Domain Specific Language):Weex 支持 Vue 语法和 Rax 语法
3.Rax 的 DSL(Domain Specific Language) 语法是基于 React JSX 语法而创造
4.但相对于 React Native,它对前端开发者的要求较低
5、一定程度减少了JS Bundle的体积,使得 bundle 里面只保留业务代码。
JavaScript 开发 + 原生渲染 的方式主要优点如下:
- 采用 Web 开发技术栈,社区庞大、有前端基础的话上手快、开发成本相对较低。
- 原生渲染,性能相比 H5 提高很多。
- 动态化较好,支持热更新。
不足:
- 渲染时需要 JavaScript 和原生之间通信,在有些场景如拖动可能会因为通信频繁导致卡顿。
- JavaScript 为脚本语言,执行时需要解释执行 (这种执行方式通常称为 JIT,即 Just In Time,指在执行时实时生成机器码),执行效率和编译类语言(编译类语言的执行方式为 AOT ,即 Ahead Of Time,指在代码执行前已经将源码进行了预处理,这种预处理通常情况下是将源码编译为机器码或某种中间码)仍有差距。
- 由于渲染依赖原生控件,不同平台的控件需要单独维护,并且当系统更新时,社区控件可能会滞后;
除此之外,其控件系统也会受到原生UI系统限制,例如,在 Android 中,手势冲突消歧规则是固定的,这在使用不同人写的控件嵌套时,手势冲突问题将会变得非常棘手。这就会导致,如果需要自定义原生渲染组件时,开发和维护成本过高。
3、自绘UI + 原生
自绘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 布局系统,且同时在开发效率上有了很大突破。
3.1、Qt
Qt 是一个1991年由 Qt Company 开发的跨平台 C++ 图形用户界面应用程序开发框架。
在近几年,虽然偶尔能听到 Qt 的声音,但一直很弱,无论 Qt 本身技术如何、设计思想如何,但事实上终究是败了,究其原因,笔者认为主要有四:
第一:Qt 移动开发社区太小,学习资料不足,生态不好。
第二:官方推广不利,支持不够。
第三:移动端发力较晚,市场已被其他动态化框架占领( Hybrid 和 RN )。
第四:在移动开发中,C++ 开发和Web开发栈相比有着先天的劣势,直接结果就是 Qt 开发效率太低。
3.2、Flutter(中文网站 https://flutterchina.club/))
Flutter相关书籍:https://book.flutterchina.club/
Flutter 是 Google 发布的一个用于创建跨平台、高性能移动应用的框架。
Flutter 实现了一个自绘引擎,使用自身的布局、绘制系统。
2021年8月底,已经有 127K 的 Star,Star 数量 Github 上排名前 20
Flutter 生态系统得以快速增长,国内外有非常多基于 Flutter 的成功案例。
1.Flutter 采用自己的渲染引擎 Skia,将 UI 渲染到画布上,具有良好的性能表现
2.如果对性能要求较高,特别是需要处理复杂动画和大量图形渲染的场景,建议选择 Flutter。
3.Flutter 则采用 Dart 语言,需要开发人员掌握新的语法和概念。
4.支持iOS、Android、Windows/MAC/Linux等多个平台,且能达到原生性能。(移动端、Web端和PC端)
Flutter和Gt对比:
- 生态:Flutter 生态系统发展迅速,社区非常活跃,无论是开发者数量还是第三方组件都已经非常可观。
- 技术支持:现在 Google 正在大力推广Flutter,Flutter 的作者中很多人都是来自Chromium团队,并且 Github上活跃度很高。另一个角度,从 Flutter 诞生到现在,频繁的版本发布也可以看出 Google 对 Flutter的投入的资源不小,所以在官方技术支持这方面,大可不必担心。
- 开发效率:一套代码,多端运行;并且在开发过程中 Flutter 的热重载可帮助开发者快速地进行测试、构建UI、添加功能并更快地修复错误。在 iOS 和 Android 模拟器或真机上可以实现毫秒级热重载,并且不会丢失状态。这真的很棒,相信我,如果你是一名原生开发者,体验了Flutter开发流后,很可能就不想重新回去做原生了,毕竟很少有人不吐槽原生开发的编译速度。
4、react-native、weex、flutter对比:
React Native:宣布放弃使用 React Native,回归使用原生技术。主要还是集中于项目庞大之后的维护困难,第三方库的良莠不齐,兼容上需要耗费更多的精力导致放弃。
可参考:
移动开发技术简介:https://book.flutterchina.club/chapter1/mobile_development_intro.html#_1-1-4-qt-mobile
现代 Hybrid 介绍(web+native混合开发)与 Flutter 入门(flutter原理):https://zhuanlan.zhihu.com/p/550771750
hybrid、react-native、weex和flutter的比较:https://juejin.cn/post/6844904013779976200
跨平台开发之react-native、weex、kotlin-native、flutter比较:https://www.jianshu.com/p/79ede74b2c21
下面这些可以不看了。。。。。上面包含下面了。。。划分也有问题,上面对的。
hybrid:
大家都知道hybrid即为web+native的混合开发模式
优点:就是拥有了web开发的服务端发布即可更新的便捷性,Android和iOS两端可以共用代码,并且web技术已经非常成熟,开发效率也会很高。
缺点:就是众所周知的性能相比native有很大的不足,且不同机型和系统版本下的兼容性较差。
React Native、Weex 和 Flutter 是目前最为热门的混合开发框架,它们各自有着优势和特点:
1、React Native
1.React Native 是由 Facebook 推出的开源框架,拥有庞大而活跃的社区,有大量的第三方组件和库可供使用。
2.React Native 基于 JavaScript,开发者可以利用已有的前端开发经验快速上手
3.开发者编写的js代码,通过 react native 的中间层转化为原生控件和操作
4.react native 运行在JavaCore中,所以不存在浏览器兼容的问题
- 最终,JS代码会被打包成一个 bundle 文件,自动添加到 App 的资源目录下。
2、Weex
- Weex 是阿里巴巴推出的开源项目,也有一个较为活跃的社区,但相对于 React Native 来说,生态系统规模稍小。
1.React Native 和 Weex 使用了 WebView 或类似的机制来渲染应用界面,性能相对较低。
2.Weex 同样基于 JavaScript,但相对于 React Native,它对前端开发者的要求较低
3.开发者可以使用Vue.js和Rax两个前端框架来进行WEEX页面开发
4.和 react native一样,weex 所有的标签也不是真实控件,JS 代码中所生成存的 dom,最后都是由 Native 端解析,再得到对应的Native控件渲染
- weex:一定程度减少了JS Bundle的体积,使得 bundle 里面只保留业务代码。
3、Flutter (中文网站https://flutterchina.club/)
- Flutter 是由 Google 开发的开源框架,虽然相对较新,但也有一个迅速增长的社区和生态系统。
1.Flutter 采用自己的渲染引擎 Skia,将 UI 渲染到画布上,具有良好的性能表现
2.如果对性能要求较高,特别是需要处理复杂动画和大量图形渲染的场景,建议选择 Flutter。
3.Flutter 则采用 Dart 语言,需要开发人员掌握新的语法和概念。
4.支持iOS、Android、Windows/MAC/Linux等多个平台,且能达到原生性能。(移动端、Web端和PC端)
4、react-native、weex、flutter对比:
React Native:宣布放弃使用 React Native,回归使用原生技术。主要还是集中于项目庞大之后的维护困难,第三方库的良莠不齐,兼容上需要耗费更多的精力导致放弃。