本文根据海康威视桌面端技能专家刘晓伦在「RTC Dev Meetup • 杭州站丨大前端年代的事务架构和跨端实践」活动中共享内容二次整理。
以下正文:
今天要与咱们共享 19 款桌面软件开发结构,我将它们分了四类,然后分别就每个类别做相应的介绍,期望经过今天的共享,协助咱们在开发的进程傍边少走一些弯路。
01 传统桌面软件开发结构
首要咱们来聊一聊传统的桌面软件开发结构。这个类别中包含咱们常见的 Qt、wxWidgets、GTK、FLTK、Swing 和 JavaFX。这六个结构有一些一起点:它们的历史都很悠长,运用的开发者也许多,并且相应的社区也很老练,其间包含了丰厚的资料。此外,它们的功用都很强大,有很多老练的事例,结构也很安稳。
可是它们用到的都是相对来说都是比较老练的技能,所以跟新式技能之间仍是有所差距,所以运用起来比较困难。
1、Qt
Qt 的优点咱们都能够在官网上看到,这儿不再赘述,其间有一点是 Qt 对各操作体系都做了很完善的封装,比方网络、文件剪切板等,假如要用体系级的 API,Qt 能够供给的十分丰厚的 API。
对于 Qt 的问题这儿介绍一下我的感受,我以为 Qt 现在的问题是发展方向不太专一,无法供给某些较大的模块,在开发进程中或许会逐步发现运用的模块不太适宜,从而抛弃这个模块,包含许多 API 也是这样,我之前用过的 Qt script 现在就现已被符号为抛弃了。
别的,Qt 的商业授权是不太友爱的。假如要开发一个商业运用,或许这儿要注意一下,有许多国内的公司都是收到过 Qt 的律师函要求收费的。Qt 还供给了许多组件,其间有一些杂乱的组件对于操控 UI 的细节是比较难的,这儿就不再举例了。
Qt 还有许多的动态链接库,假如要做静态链接也是比较难的,当然社区中供给了一种方法,便是能够编译 Qt 的源码做静态链接,可是这就又要触及版权的问题了。
2、GTK
GTK 结构比较偏 Linux,在 Linux 中有许多桌面运用都是用 GTK 开发的,在 Windows 下 GTK 相对较少,并且在 Windows 体系下的静态链接也是比较难的,甚至搭环境都比在 Linux 体系下要难得多。
别的,GTK 在 Windows 下也做了体系 API 的封装,可是在 Windows 下的封装比在 Linux 体系下的封装要少一些。也便是说,有些 API 在 Linux 下能用,而在 Windows 下是不能用的,这样的 API 不在少数。最后 GTK 的商业授权是十分友爱的。
3、FLTK
FLTK 结构是 C++ 之父引荐运用的,它便是一个十分轻量的 GUI 结构,可是轻量意味着功用是缺乏的,它的功用比较少,几乎不做体系 API 的封装,大部分都要开发人员自己用 C++ 编写。这样导致开发人员在每个渠道上都要从头编写,比方要敞开一个跨渠道的图片运用,那么在 Windows 下调用一些体系级的 API 进行完结,在 Mac 下或许又要完结一遍。
FLTK 的优点是它的产品很小,因此它编译出来的东西能够做到很小,并且功用也十分好(比前两个都好)。FLTK 的商业授权也很友爱,能够支撑静态链接。可是 FLTK 有一些缺乏,便是由于它是一个 GUI 结构,因此在制作 GUI 组件这方面是不太好的。
我在运用 FLTK 的时分发现,在其间做动画操控、组件叠加(这时用到便是肯定定位,就需求对组件的层级进行操控)都会遇到问题。别的,在制作圆角的时分,虽然 FLTK 供给了相关的功用,可是用户还要操控圆角的特别大小、某一个圆角呈现等,这些都要写十分杂乱的代码。
4、wxWidgets
wxWidgets 跟前面 3 个结构有所区别,它是根据操作体系的 API 来做桌面运用的,也便是说,在 Windows 下开发一个桌面运用时,看起来就像是传统的 Windows 桌面软件的风格,在 Mac 下则是 Mac 的风格,而前面三个都有自己的自绘引擎。
也便是说,在前面三个结构中做一个按钮,不管用什么样的制作方法,在三个渠道下表现都是一起的,可是 wxWidgets 在三个渠道上都是依照三个渠道自己的 API 来制作这个按钮的。wxWidgets 供给了十分多的操作体系的 API,并且能够做到静态链接,但小问题比较多。
5、Swing/JavaFX
Swing /JavaFX 是根据 Java 的技能栈来做桌面运用的,由于要依靠 JVM,所以体系 API 比较多,但功用会一般,这两个结构或许相对来说用得少一些。
假如咱们在这几个桌面软件结构傍边做挑选的话,我个人引荐仍是用 Qt。
02 新式桌面软件开发结构
方才咱们说的一些结构或许用的技能比较陈旧,咱们开发起来比较麻烦。新式的结构,比方微软的 MAUI、谷歌的 Flutter Desktop 和 JetBrains 公司的 Compose Multiplatform,都是选用十分新的技能来做的,开发起来很简单,开发体验也十分好。
可是由于这几个结构都比较新,基本上都是本年发布的正式版(最早是 Compose Multiplatform 发布的,然后依次是 lutter Desktop 和 MAUI),所以社区相对来说不如前面几个结构老练,资料和成功事例也相对来说少一些。
1、MAUI
MAUI 是用 XAML 是写界面和逻辑的,咱们假如用 WPF 写过软件的话,应该会对这项技能很了解。MAUI 用 C# 编写事务逻辑,只兼容 Windows 操作体系和 Mac 操作体系。MAUI 在 Linux 下是社区供给的一套支撑体系,或许会有一些问题。别的,MAUI 是依靠 .NET 结构的,API 比较多,并且支撑移动端(这三个结构都是支撑移动端的,新式的开发结构都兼容移动端的开发)。
2、Flutter Desktop
Flutter Desktop 是运用 dart 编写界面逻辑的,它的组件比较丰厚,并且支撑 Win 10 操作体系(之前的操作体系就不太支撑了),API 是比较少的,需求开发人员自己来写。
3、Compose Multiplatform
Compose Multiplatform 依靠 JVM,是用 Kotlin 编写逻辑的界面和逻辑的,有消息说将来或许会推出 Kotlin/native*,这样就能够不必依靠 JVM 了,可是这或许还比较遥远的事情。Compose Multiplatform 的组件也是比较丰厚的,咱们都知道 Java 社区中有许多结构、模块等都能够运用,并且也是支撑运用端的。
在这几类结构里中我引荐咱们运用 Flutter Desktop,虽然它们都是新式的结构,所以很难说哪一个将来会更受欢迎,可是根据它们的一起点(技能更现代化、愈加易用、资料较少、社区不老练、成功事例较少、用户较少、不安稳),我仍是引荐 Flutter Desktop。
03 根据浏览器的桌面软件开发结构
根据浏览器的桌面软件开发结构相对较多,比方 Electron、NW.js、CEF、Sciter、WebView2、webview 和 TAURI。其间运用 Electron 比较多,也现已十分老练。它们的一起点是它们能够复用浏览器的技能,比方 html、JS 和 CSS 等一系列生态中的组件。
除此之外,它们还能够做十分绚丽的界面,由于 Web 技能发展这么年,CSS、html 等在符号和操控界面特性方面的技能都现已十分老练,不像方才说到的 FLTK 要做叠加动画作用都十分困难,假如用这些技能做这些界面会十分从容。但这些结构的功用也是有强有弱。
1、Electron/NW.js
Electron 和 NW.js 这两个结构是十分类似的技能,它们都是把 Chromium 与 Node.js 集成到一起,让开发者能够只运用前端技能开发桌面运用。假如要访问体系的 API,就用 Node.js 供给的 API,当然也有一些特别的 API,比方创立桌面图标、访问剪切板、操控窗口大小等,是 Electron 结构自身供给的,而不是 Node.js 供给的,也不是传统 HTML 体系供给的,是在其间做了一些附加的操作,当然 NW.js 也有。
这两个结构的作者都有很深的根由,这儿就不细说了。我个人觉得 NW.js 完结起来相对来说比较巧妙,对开发者比较友爱,而 Electron 保护更给力,社区也很庞大。
2、CEF/WebView2
CEF 和 WebView2 结构都是直接根据 Chromium 开发的。CEF 的历史比较悠长,并且更灵敏,咱们能够经过这个结构进行自在的操控,API 也更多。
WebView2 是微软的短期团队供给的一个结构,这个结构也是直接根据根据 Chromium 做的封装,它供给了 .NET 和 C++ 的 API,咱们能够用 .NET、C++ 或许 C#言语去操作这个结构,现在还不支撑 MAC(将来或许会支撑)。
相对来说 CEF 更像作者个人在保护,WebView2 就更像一个团队,可是由于 WebView2 不开源,所以也没法参加。
3、webview/TAURI
webview 和 TAURI 运用操作体系内配置的浏览器中心,比方应该在 Windows 下布置,那么就用 WebView2;假如在 Mac 下布置,就用 WKWebView;假如在 Linux 下布置,就用 webkitgtk 来做烘托,因此这儿或许就会有一些兼容性的问题。
在做前端的时分经常会碰到一些兼容性的问题,可是现在来看,由于它们都是比较现代的浏览器中心了,所以这个问题还没有这么明显。别的,TAURI 是使⽤ Rust 开发的,假如要挑选这个结构,或许还得了解 Rust 言语。
4、Sciter
Sciter 是一个比较特别的结构,这儿把它单列出来,Sciter 做了许多的减少,能够把产品的体积缩减到 10M 以内,前面几种结构基本上只要把浏览器中心分发给用户,即便紧缩过后也得 60M。
Sciter 以前有一个自己的脚本叫 TIscript,现在用的是 QuickJS,它的功用十分强大,并且集成了 skia 的中心版别。我不知道咱们有没有关注过一个叫作 rustdesk 的项目,之前它挑选的便是 Sciter 结构,当然这个结构的小问题也会比较多。
假如咱们挑选这类结构,我引荐运用 Electron/CEF 结构。假如团队中没有 C++ 开发人员,或许不易于运用 C++ 进行开发运用,就挑选 Electron;假如有 C++ 开发人员,并且运用十分重视功用,就挑选 CEF。
04 即时烘托桌面软件开发结构
即时烘托相对运用的是坚持形式的桌面运用结构,一般做桌面运用都是哪里需求更新,就更新哪里,结构会进行烘托。可是即时烘托是不一样的,它是每刷新一帧,就会把显现的内容都更新一遍,也便是说每一帧都会悉数更新一遍。
所以这类结构有一个一起的特点,便是它们要耗费 CPU 和 GPU 资源,传统结构的配置都是坚持形式,假如不更新是不会做烘托的。别的,这种结构与游戏运用能够无缝对接,可是传统运用事例比较少,小问题比较多,且尚在发展中。
1、Dear ImGui
即时烘托桌面软件开发结构中,Dear ImGui 比较流行,最近作者在开发 Dock 形式,估计本年有或许会推出,到时分咱们能够去测验一下。
它的开发方法是比较特别的,便是每个循环都在做烘托。比方运用 Dear ImGui 做事情开发时,会将某一个变量设置为 true 或许 false, 在这一轮烘托的进程傍边是 true,在它下一轮烘托进程傍边,我发现变成 false 了,咱们就以为触发了某个事情。而不是像 web 开发领域中,当呈现一个 event 时,另一个组件就能够接收到它。
2、Nuklear
Nuklear 是使⽤ C 语⾔开发的,更贴近 C 开发者的习气,⽤户相对 Dear ImGui 更少、⼩问题更多。
3、RmIui
RmlUi 比较特别,它不是即时烘托结构,可是却有即时烘托结构的通病,便是用它开发运用之后会继续耗费 CPU 和 GPU 资源,它能够运用 HTML 和 CSS 描绘界面,上手相对比较难,开发十分灵敏,界面也很灵敏,资源耗费相对更多。
我最近一向在用这个结构,也跟作者进行了深化的沟通。这个结构开发出来的运用程序能够做到 2M 左右,它能够解析你的 HTML,做一些十分特别的作用,比方阴影、突变之类的动画,可是它很小,不像浏览器一样,即便紧缩也得 60 多兆,这也是它的优势。
这几类结构中我个人引荐 RmlUi,假如到作者的项目中进行发问,他基本上隔天就会回复。
05 总结
在做总结之前,我先简述一下这几个结构的对比。
其实咱们在介绍传统的桌面开发结构的时分,Qt 和 wxWidgets 内置的组件也有根据浏览器的, 便是 QWebEngin 和 wxWebView,QWebEngin 封装的是 Chromium 的中心,其实与 CEF 和 QWebEngin 挺像的,可是许多人在用 Qt 的时分,是把 CEF 集成到 Qt 中,反而不必 QWebEngin。
他们坚持的观点便是 QWebEngin 还不老练,功用力相对来较弱,不如 CEF,可是现在来看,我个人以为,在 Qt 6.2 和 Qt 6.3 之后,QWebEngin 的 API 会更多,运用的需求更简单满意。
wxWebView 更像是 webview 和 TAURI,它也是在不同的操作体系上运用操作体系的浏览器中心,这儿就不多说了。
再看一下 RmlUi 和 Sciter 的对比。RmlUi 能够用 html 和 CSS,Sciter 也能够用 html 和 CSS,由于 Sciter 集成了 QuickJS,所以它也能够写 JS 代码(可是也得写 C++,由于你不或许不必操作体系的 API,可是它的 C++或许会比 RmlUi 的 C++ 代码量要少许多)。两个结构都不支撑悉数的 html 和 CSS 规范。
假如要选一个桌面软件开发结构,应该承认偏重哪方面的才能,我以为有三方面的才能是需求重视的:
- 界面的描绘才能:比方布局、元素定位、圆角、阴影、突变
- 事情处理才能:比方鼠标事情、键盘事情、触屏事情、媒体播放完毕、网络状况变更等
- 异步处理才能:处理事务逻辑的时分,界面烘托作业不能暂停
别的,桌面软件开发结构各有各的优势,比方软件开发逻辑很杂乱,并且要快速地完结,那么 BrowserCore 或许是一个不错的方法,由于用前端技能来编写速度更快,可是假如软件需求更少的资源耗费和更快的运行速度,那么就需求考虑 Native 方法。
最后,要做桌面运用开发需求了解一些底层知识,比方多线程、多进程的操控;各种通信协议;⽇志搜集;版别操控;设计形式与架构准则;本地数据操控;操作体系。
06 问答环节
1、用 Electron 怎样处理 crash?
Electron 也有十分多问题,它也会溃散,并且有溃散陈述的搜集方法,搜集这些陈述之后还要进行分析,可是分析出来的溃散陈述实并不能很明确地反映到底是哪一行代码、哪一段事务出了问题。许多时分溃散陈述中或许更多的是阐明一个指针指向的内存呈现了问题,这时一种方法是尽量联络用户复现问题;第二种方法是做很多的主动化测验,收窄问题的规模,将其局限在一定的规模内再做精细化处理;第三种方法便是做 AB 测验。
2、Electron 开发的运用安装包太大这个问题有没有好的解决方法。别的,开发者该怎么开发 Electron 运用的看护进程。
这是两个问题。第一个问题便是包太大的问题,这个其实是挺难解决的,在立项之前就应该跟团队负责人沟通好需求,是要快速的事务开发,仍是更高的功用,更小的体积?假如要更小的体积,那么就放弃事务开发效率。能够运用 C++ 做一些作业,仅仅会耗费更长的时间和更多的资源。在打包的时分,要先承认是否用的是 LZMA 紧缩格局,这种格局能够紧缩得更小一点,可是小不了多少,最低或许仍是 60 多兆。
至于怎样做看护进程,这个问题现在有两种方法,一种是写一个独立的运用,在 Electron 发动的时分运用就能够随之发动,然后它看护 Electron 进程。假如 Electron 进程溃散的时分,就由它来发动 Electron 进程。
另一种方法是分析运用为什么溃散,是主进程溃散了,仍是烘托的时分溃散了,你假如主进程溃散了,尽量仍是要找到其溃散的原因,由于一旦主进程溃散,那么所有烘托都会失败;假如是烘托进程溃散了,那么能够在主进程中翻开一个其他的进程,来确保将烘托溃散的通知发送给用户,由用户重启烘托进程,或许主动重启。