这篇是用来水《认知实习》的结课论文的,参考了以前写的一篇关于 GUI 开发框架的博客,借着这个机会顺便对那篇博文进行了一次修改作为一篇新博文,老文新水了属于是

这个报告只是单纯的应付作业,不要太注意细节

跨平台应用开发框架技术的发展应用与展望

随着移动设备的广泛普及,跨平台应用开发框架成为解决不同操作系统底层API差异的关键工具。本 文回顾了桌面端和移动端跨平台框架的发展历程,在桌面端,从早期的调用API 或自绘技术到如今以CEF 库的应用为代表的框架。在移动端,Web应用、原生渲染技术和自绘方案分别应对挑战与机遇,而UI描述 方式也经历了从混合到声明式、组件化的演变。未来,随着移动设备技术的进步,跨平台开发框架有望在 提高开发效率的同时,进一步优化用户体验。这一领域的创新将继续推动应用开发工具和方法的演进,为 开发者提供更高效、灵活的解决方案。

背景

近年来,随着智能手机和平板电脑等移动设备的广泛普及,移动端应用开发一直备受关注。然而,由 于不同移动端平台(iOS、Android)之间底层API 存在差异,大多数应用程序提供商不得不雇佣两组开发 人员,以适配不同平台。为了解决这一问题、降低开发成本并为用户提供在不同平台上相似的使用体验, 跨平台应用程序开发框架应运而生。这些框架有望有效解决跨平台开发中的挑战,为开发者提供更高效的 工具和方法。

“一次编写,多处运行”的理念并不是新鲜的想法。早在POSIX(Portable Operating System Interface) 提出时,就引起了广泛关注。POSIX提供了一个可移植的操作系统接口,使得在不同的UNIX系统上能够轻 松地移植和运行应用程序。

这种理念也在后来的技术中得到了体现。例如,Java程序通过Java虚拟机(JVM)实现在任何支持Java 的平台上运行。使用Web技术(HTML、CSS、JavaScript等),开发者可以创建跨平台的应用程序,通过浏 览器在各种设备上运行,实现了跨平台和跨设备的编程。另外,使用Docker和Kubernetes等容器技术允 许开发者将应用程序及其所有依赖项封装在一个容器中,确保在不同环境中一致地运行。

桌面端跨平台框架的发展历程

跨平台应用软件的开发体现了“一次编写,多处运行”的理念,这在PC端应用开发中具有悠久的历史。 早在上世纪90年代,经典的跨平台桌面GUI开发框架就涌现出两种主要思路:一是通过调用不同操作系统 的 API 接口实现,以 wxWidgets 为代表;另一是通过自绘引擎在不同操作系统上显示相同内容,以 Qt、 GTK+、FLTK 为代表。

以 Qt 为例,该框架的运行效率高,在诸如工控等行业得到了广泛应用,也常被用来开发对效率有一 定要求的跨平台软件,例如WPS Office 就采用了Qt 进行开发,这使得它能在不同桌面端提供几乎相同的 用户体验,在移植到众多基于 Linux 的国产系统上具有优势。

网页端的HTML + CSS + JavaScript组合在界面绘制方面具有难以比拟的优势,通过内置Chromium, 开发者就可以借用 Chromium 成熟的界面渲染引擎来绘制界面、 DOM, V8引擎等等功能,从而实现跨平台 的应用开发。大量软件使用了 CEF (Chromium Embedded Framework) 来实现丰富的功能。而更进一步,通 过 Node.js,开发者甚至可以使用 JavaScript 来编写几乎全部的客户端代码,典型的例子是 NW.js 和 Electron。

Electron 是 GitHub 开源的一个跨平台桌面应用开发框架,它通过将 Chromium 和 Node.js 合并到 同一个运行时环境中,并将其打包成 Mac、Windows 和 Linux 系统下的应用,从而使得开发者可以使用 HTML、CSS 和 JavaScript 来开发跨平台的桌面应用。Electron 的出现,使得跨平台桌面应用开发变得更 加简单,也使得跨平台桌面应用的开发成本大大降低,因此受到了广泛的关注和应用,许多我们熟知的软 件都是基于 Electron 开发的,如 Visual Studio Code、QQ、网易云音乐等。

然而,无论是通过一个 libcef.dll 来动态链接CEF 运行时,还是直接通过 Electron 来打包一个 Chromium 运行时,都会带来巨大的体积开销。另一种类似的方案应运而生:同样依托于 Chromium,但是 自身不附带 CEF 运行时,而是直接调用不同系统中自带的 Chromium 运行时,从而实现跨平台的应用分 发。这种方案的代表有 webview、TAURI、Sciter 等,它们虽然体积更为轻量,但由于不能保证不同系统 中 Chromium 的版本一致,因此在应用上有一定的局限性。

移动端跨平台框架的发展历程

在移动平台上,为了实现跨平台的开发 (主要是 Android 端 和 iOS 端 ) 出现了三种解决方案

Web 应用:通过借用系统 Webview 或者内置 WebView 进行绘制、功能实现,典型代表如 PWA (Progressive Web Apps)、微信小程序等,以微信小程序为例,通过 WeixinJSBridge 来调用微信中的 Webview。这种开发方式具有很短的开发周期,产出效率高,对开发人员的要求较低,但 Web 应用的效率 相比原生应用要低。

原生渲染技术: 针对调用 Webview 绘制速度较慢的问题,这种技术不通过 webview 来渲染,而是通 过 js 通过 JS 来调用系统的原生控件,阿里的 Weex 框架与 Meta的 React Native 框架就采用了这样 的方法,微信小程序同样也有这样的实现,比如通过 Hybrid 技术引入原生组件等。然而,即使是这样, 其运行效率还是相比原生绘制要慢。

通过自绘来实现流畅运行的方案: 这种方案既不使用 WebView,也不使用设备附带的 OEM Widget,而 是使用自己的高性能渲染引擎来绘制 Widget。典型代表为2017 年由 google 公司推出的Flutter 框架。

界面描述方式的演变

UI 的描述方式一直是GUI开发中的关键话题。在早期开发中,通常采用将功能和UI融合在一起的思 路。然而,随着界面变得更为复杂和精致,这种方法变得不够有效。为了解决这一问题,基于"关注点分离 "的原则, 开始使用专门的界面绘制文件,将界面和功能进行了分离。经典的案例包括WPF采用XML,Qt采 用QML,以及在浏览器端的HTML定义基本结构,CSS进一步将UI分离,JavaScript实现功能。

而在浏览器端,随着用户对更流畅、无缝的用户体验的追求,单页面应用(SPA)成为一种流行的开发 模式。前端框架如Angular、React和Vue.js的兴起,引入了声明式、组件化思想和虚拟DOM,使得界面的 描述更为动态和高效。而随着应用复杂性的增加,状态管理变得至关重要。Redux、Vuex等状态管理库的引 入,使得界面描述方式更加关注数据的流动和管理。全局状态的概念有助于不同组件之间的通信和数据同 步。

这种思想至少可以追溯到 WPF 为代表的MVVM 模型,先前的MVC 模型将数据的改动通过控制器(Controller) 发送到模型(Model),模型再将新的状态通过控制器发送到界面(View)。这样的处理使得创建和更新 UI 元素的操作被分离开,容易造成它们的不同步。而采用 MVVM 模式(Model-View-ViewModel),将视图的逻 辑与外观分离。通过引入ViewModel 层,将视图的代码从其代码后台中提取出来,实现了对数据和业务逻 辑的有效管理。在MVVM 中,ViewModel 负责暴露数据和操作,供视图消费,实现了视图的极简代码后台, 同时通过数据绑定连接视图和ViewModel。这种模式促进了关注点的清晰分离,使代码更易于维护和扩展。

这种想法无疑也影响了客户端的开发:无论是苹果推出的用于构建iOS应用界面的声明式框架 Swift UI。还是谷歌为Android平台推出的采用Kotlin语言的现代UI工具包Jetpack Compose,都引入了声明 式编程模型,支持组件化的开发方式,允许开发者使用简单而强大的语法来构建交互式和动态的用户界面。

很自然的,更新兴的跨平台软件开发框架也都沿袭了这种想法。使用React框架的React Native自然 不必多言。React Native 将界面的描述和应用的逻辑分离,使得开发者可以专注于构建交互式UI组件, 而不用担心底层原生控件的细节。

Flutter 同样采用组件化和声明式的开发方式,Flutter 的 UI 由指令式的面向对象语言构建,也就 是 Dart。Flutter 本身并不包含声明式的标记语言,而是将 UI 交给代码来动态构建,这种“代码优先” 的开发使得热重载以及动态环境适配等特性能更好地得以实现。

Flutter 框架的架构概览

Flutter 和 Qt 在底层实现上有相似之处。对于底层操作系统而言,应用程序在每个平台上都包含一 个特定的嵌入层,提供程序入口,与底层操作系统进行协调,并访问诸如 surface 渲染、辅助功能和输入 等服务,同时管理事件循环队列。

嵌入层承载着作为核心部分的Flutter 引擎。Flutter 引擎提供了 Flutter 应用所需的接口,负责 对需要合成的场景进行渲染和功能执行,包括图形、文本布局、文件及网络 IO、辅助功能支持、插件架构 以及 Dart 运行环境等。引擎将底层 C++ 代码包装成 Dart 代码,通过 dart:ui 暴露给 Flutter 框架 层。这个库暴露了最底层的接口,包括用于驱动输入、图形和文本渲染的子系统的类,允许开发者通过 Flutter 框架层与 Flutter 进行交互。

图表 Flutter architectural overview-1

总结与展望

近年来,随着移动设备的普及,跨平台应用开发框架成为解决iOS和Android底层API差异的重要工 具。从桌面端到移动端,这一领域经历了不同的发展历程。

在桌面端,早期采用调用不同操作系统API接口的方式,如wxWidgets,Qt等。后来,通过Web技术 和容器技术,实现了一次编写多处运行的目标,例如Electron框架。然而,体积开销成为一个问题,推动 了新的轻量方案的出现,如webview、TAURI、Sciter等。

移动端跨平台框架面临着不同的挑战与机遇。Web 应用、原生渲染技术和自绘方案分别采用不同的策 略。Flutter 作为谷歌推出的框架,通过显式剥离基础状态和用户界面,实现了高性能的渲染引擎,成为一 种创新的跨平台解决方案。

UI 描述方式也在不断演变,从早期将功能和UI融合到关注点分离,再到声明式框架的兴起,如React、 Vue.js 等。这种思想影响了客户端开发,例如Swift UI和Jetpack Compose的引入。跨平台框架也采用 了这种声明式、组件化的开发方式,例如React Native和Flutter。

Flutter 的架构通过嵌入层承载引擎,使用 C++实现底层操作系统协调和渲染等功能。这一架构使得 Flutter 能够在不同平台上提供一致的用户体验。

跨平台应用开发框架在不同阶段都经历了技术的演进与创新,为开发者提供了更高效、灵活的工具和 方法。未来,随着移动设备技术的不断发展,跨平台开发框架有望在提高开发效率的同时,进一步优化用 户体验。

参考文献:

[1] Windmill E. Flutter in Action. 1st Edition. New York, USA: Manning; 2019.
[2] Palumbo, Daniele. “The Flutter framework: Analysis in a mobile enterprise environment.” PhD diss., Thesis, Turin, IT: Politecnico di Torino, accessed May 17, 2022, https://webthesis. biblio. polito. it/19111/1/tesi. pdf, 2021.
[3] Dagne, Lukas. “Flutter for cross-platform App and SDK development.” [D]. Metropolia University of Applied Sciences (2019).
[4] C. Anderson, “The model-view-ViewModel (MVVM) design pattern,” in Pro Business Applications with Silverlight 5Anonymous United States: Apress L. P, 2012, pp. 461-499.