write once,run everywhere
开发一个APP运行在Android手机需要一套代码,运行在ios操作系统的手机又需要一套代码,为了使同一套代码能运行在不同的操作系统上,解决多端独立开发的问题,跨平台技术便应运而生。
Android 应用采用 Java 或 Kotlin 编写,iOS 应用采用 Objective-C 或 Swift 编写,Web 端采用 HTML /CSS/JavaScript 编写。当需要开发支持多端的应用,每一端都需要独立研发、测试,一直到上线,以及后续的维护工作,工作量成倍增涨,势必延长研发周期。需要Android和iOS两端开发,两个技术团队,人力成本高。
我们知道Java是可以在Windows Linux Unix不同的操作系统上运行的,介绍一下它是怎么做到的。
图中展示了Java程序运行的过程,其中一个重要的环节是JVM(Java Virtual Machine),JVM负责将字节码文件翻译成特定平台下的机器码然后运行。
同一套Java代码,想要在不同的操作系统上运行,只需要改变虚拟机的版本就可以做到。
注意:跨平台的是Java程序,不是JVM。JVM是用C/C++开发的,不同平台下需要安装不同版本的JVM。JVM在Java/bin 里面,也就是说需要下载安装不同版本的jdk。
常见的跨平台技术主要有三种:重点介绍Flutter
上表中开发语言主要指应用层的开发语言,而开发效率,是指整个开发周期的效率,包括编码时间、调试时间、以及排错、处理兼容性问题时间。动态化主要指是否支持动态下发代码和是否支持热更新。值得注意的是 Flutter 的Release 包默认是使用 Dart AOT 模式编译的,所以不支持动态化,但 Dart 还有 JIT 或 snapshot 运行方式,这些模式都是支持动态化的。
相当于做一个网页版的app,在原生的浏览器中跑自己的网页,Android和ios各跑一个浏览器。
由于 H5 代码只需要一次开发,就能同时在 Android 和 iOS 两个平台运行,这也可以减小开发成本,也就是说,H5 部分功能越多,开发成本就越小。我们称这种 H5 + 原生 的开发模式为混合开发 ,采用混合模式开发的App我们称之为混合应用或 HTMLybrid App ,如果一个应用的大多数功能都是 H5 实现的话,我们称其为 Web App 。
优点是:动态内容可以用 H5开发,而H5是Web 技术栈,Web技术栈生态开放且社区资源丰富,整体开发效率高。
缺点是:性能体验不佳,对于复杂用户界面或动画,WebView 有时会不堪重任。
用原生的组件,让开发者去写网页版的代码,将网页版的代码转化(解释)成原生的组件,这样的话用户体验到的确实是原生的组件,比如开发者写:我想要一个文本框。React Native就会在Android 放一个安卓的文本框,在iOS放iOS的文本框。
优点:
缺点:
在一个全新的角度,既不写网页的代码打包到浏览器中,也不像React Native用原生的组件,Flutter学习unity游戏引擎,在每一个平台上做一个渲染引擎,开发者写的代码都能在这些渲染引擎上运行,达到的效果是一样的,类似JVM。
开发者写Dart的代码在渲染引擎上渲染出来的效果是一样的,Dart的代码可以可以直接编译成二进制可执行文件,再加上自己的渲染引擎,自己所有的东西都是可控的,解决了React Native频繁交互带来的性能问题,所以性能会提升很多。
skia(Chrome的渲染引擎),很成熟,在各个端都可以打包,渲染引擎可以放在各个平台上:Android iOS Windows Linux Mac
不用太担心原生的一些变动和限制,比如:iOS原生更新一个功能,需要iOS16才能使用,这时如果你想使用就必须要更新到iOS16。Dart和Flutter来说,完全可以使用到Dart和Flutter的最新功能,而且他们支持很老的系统版本。
Dart是Flutter的基础。
与其他许多空安全语言不同, Dart 提供健全空值安全,据说可以避免很多Bug。
Dart 的编译器技术可让您以不同的方式运行代码:
原生平台:针对面向移动和桌面设备的应用程序, Dart 拥有具有实时 (JIT) 编译功能的 Dart VM 和用于生成机器代码的提前 (AOT) 编译器。
Web 平台:Dart 可用于编译开发和生产阶段的面向 Web 的应用,它的 Web 编译器可以将 Dart 转换为 JavaScript。
注意:自绘引擎解决的是 UI 的跨平台问题,如果涉及其他系统能力调用,依然要涉及原生开发。
优点:
性能高;由于自绘引擎是直接调用系统API来绘制UI,所以性能和原生控件接近。
灵活、组件库易维护、UI外观保真度和一致性高;由于UI渲染不依赖原生控件,也就不需要根据不同平台的控件单独维护一套组件库,所以代码容易维护。由于组件库是同一套代码、同一个渲染引擎,所以在不同平台,组件显示外观可以做到高保真和高一致性;另外,由于不依赖原生控件,也就不会受原生布局系统的限制,这样布局系统会非常灵活。
缺点:
框架层是纯dart语言实现的一个响应式框架(VUE也是响应式),由许多抽象的层级组成。通常情况下,开发人员通过Flutter Framework 与 Flutter 进行交互,Flutter 框架提供了一个用 Dart 语言编写的现代、反应式框架。它包括一套丰富的平台、布局和基础库,由一系列的层组成。从上到下有:
渲染层 用于提供操作布局的抽象。有了渲染层,你可以构建一棵可渲染对象的树。在你动态更新这些对象时,渲染树也会自动根据你的变更来更新布局。
widget 层 是一种组合的抽象。每一个渲染层中的渲染对象,都在 widgets 层中有一个对应的类。此外,widgets 层让你可以自由组合你需要复用的各种类。响应式编程模型就在该层级中被引入。
引擎层。毫无疑问是 Flutter 的核心, 该层主要是 C++ 实现,其中包括了 Skia 引擎、Dart 运行时(Dart runtime)、文字排版引擎等。在代码调用 dart:ui库时,调用最终会走到引擎层,然后实现真正的绘制和显示。
嵌入层。Flutter 最终渲染、交互是要依赖其所在平台的操作系统 API,嵌入层主要是将 Flutter 引擎 ”安装“ 到特定平台上。嵌入层采用了当前平台的语言编写,例如 Android 使用的是 Java 和 C++, iOS 和 macOS 使用的是 Objective-C 和 Objective-C++,Windows 和 Linux 使用的是 C++。 Flutter 代码可以通过嵌入层,以模块方式集成到现有的应用中,也可以作为应用的主体。Flutter 本身包含了各个常见平台的嵌入层,假如以后 Flutter 要支持新的平台,则需要针对该新的平台编写一个嵌入层。
通常来说,开发者不需要感知到Engine和Embedder的存在(如果不需要调用平台的系统服务),Framework是开发者需要直接交互的,因而也在整个分层架构模型的最上层。
参考文档:
跨平台技术演进及Flutter未来 - 知乎 (zhihu.com)
Java期末复习1_Ipkiss工作室的博客-CSDN博客
Java是如何实现跨平台的_Bird鸟人的博客-CSDN博客
hybrid技术_. . . . .的博客-CSDN博客
跨平台开发该不该用Flutter?2023年版Flutter全面解析_哔哩哔哩_bilibili
简介 · React Native 中文网
RN通信机制和渲染流程_rn 引擎渲染周期_浅夏晴空的博客-CSDN博客
Dart 编程语言主页 | Dart 中文文档 | Dart
Flutter 架构概览 - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter
Flutter 笔记 | Flutter 核心原理(一)架构和生命周期_flutter核心原理_川峰的博客-CSDN博客