快手、孩子王、华为等专家分享大模型在电商运营、母婴消费、翻译等行业场景的实际应用 了解详情
写点什么

桌面版应用程序的前世今生

  • 2019-11-04
  • 本文字数:3479 字

    阅读完需:约 11 分钟

桌面版应用程序的前世今生

互联网出现之前,C/S 架构是软件产品的主流,后面渐渐地被 B/S 架构所取代(因为不需要配置客户端),但由于浏览器有刷新机制,服务器的负载等因素,C/S 架构的响应速度和流畅性是好于 B/S 架构的,所以现在软件开发的趋势是两者的融合,一般是 B/S 架构开发的产品可以非常方便地转移到 C/S 架构下。客户端(client)是 C/S 架构软件产品中重要的一部分,除了和用户交互、本地处理数据的强大功能,顺畅的体验和美观的样式也是客户端技术追求的目标。这里和大家介绍桌面版应用程序的一些历史和现在比较流行的 electron 技术。

桌面版应用程序历史

桌面应用程序,又称为 GUI 程序。可以分为以下几个阶段:


  • VB,上古程序员的开发工具,曾经全球第一的开发语言,拖拽式的图形化开发让它成为极佳的桌面开发工具。微软依靠其操作系统的优势,一直压制同时期的竞争对手 delphi。微策略早期应用该技术,开发了管理智能商务平台的大杀器 developer。

  • C++、win32API 的 MFC 方案是基于窗口中组合控件和消息传递机制。这也是 20 多年前的技术,所以 API 设计的不是很友好。几年前微软已经停止维护,简单来说它已经过时了。

  • Winform 微策略几年前基于该技术研发第一代的 Desktop 版本,但是从开发体验角度来说自定义、美化控件会比较麻烦。

  • C# .net framework,代表就是 WPF,它的原生特性是其他类库无法比拟的:High DPI、Split Screen 以及对 DirectX 的天然优势。但是并不开源,需要依赖.net 框架,还有就是启动会比较慢。Workstation Windows 的新客户端就是基于该技术研发。

  • Java swing/javaFx,这是一类比较大的阵营,优势是跨平台和流行开发语言 Java 的天然结合,但开发出来的界面作者个人认为并不美观。

  • C++ Qt,这是很多客户端跨平台的首选,因为开源、UI 库和各种功能的类库非常丰富,但是学习成本比较高。

  • C++ duilib,这是 windows 下开源的 directUI(微软提出的分离 UI 和逻辑的思想)库,它是迎合互联网桌面软件小而美的趋势发展起来的,可能大家对它的关注度比较少。但是用它开发出的产品大名鼎鼎,比如 QQ、微信、爱奇艺等很多知名度高的软件。

  • Objective-c/swift cocoa,这是 mac 平台下的方案。可以方便调用底层的 API,缺点是不跨平台,文档不友好,UI 库并不丰富。现在这种方式开发的越来越少了。

基于 Web 技术的桌面应用开发

从 B/S 和 C/S 架构逐渐融合的角度来说,基于 Web 技术进行桌面程序的开发渐渐变成了主流。因为对界面的代码部分可以做到复用。


这类技术早期的方案是用 vb 内嵌 webBrowser 控件,基于 IE 内核,正好很多网页开发也有用 activeX 的需求,但这种方式具有明显的缺陷——非常依赖于用户的环境,会因为组件缺失导致程序各种崩溃。第二类是嵌入式网页框架,这类技术主要是基于浏览器引擎实现 UI 渲染。比较典型的就是 appkit 上面 UIWebView 和 CEF(chro-mium embeded framework)。这种方法可以使用网页 HTML5+CSS 实现各种酷炫的效果,但是缺点也比较明显,就是桌面程序里面嵌入了一个类似 Chrome 的浏览器,内存的开销会比较大。


后面出现了 nwjs 和 electron,electron 相比 CEF 有了单独执行 js 的 v8 引擎,可以运行 NodeJS 来完成服务器端功能,通过和内部浏览器的 v8 引擎交互可以实现一个独立的客户端,这不同于 CEF 需要寄宿在其他程序内部。

Electron


用 Electron 来做桌面程序开发的优势明显,相当于是完全的网页编程,有 Web 开发经验的前端开发上手非常容易。Web 开发生态广泛,开发成本低,可扩展性强,一些流行的前端框架例如 React、Angular、Vue 都可以和 electron 结合进行开发。另外它也具备和 Qt 一样跨平台的优良特性。对性能要求不高的桌面版程序来说,一份代码同时得到网页版和各个平台的桌面版,开发的效率是其他方案无法比的。可以说,这是大部分人看好的趋势。

和 Web 开发的区别

前端开发的一个痛点就是经常需要考虑多种浏览器之间的兼容,但是使用 electron 开发则不存在这样的问题,它只需要考虑 electron 中对应 Chrome 的版本。另一个使用 electron 解决的痛点是跨域,它可以绕过客户端直接通过 NodeJS 里的 request 通信模块发出请求,这样就无需被跨域所困扰。

扩展能力

node-ffi 可以在 NodeJS 环境中调用动态链接库接口。通过这种方式,我们可以把 JavaScript 方法映射到动态链接库接口,从而实现 C++ 类库的接入。

Electron 运行原理


Electron 的运行机制可以从两种进程说起:主进程和渲染进程。运行 package.json 的称为主进程,它可以负责创建渲染进程(多个)。下图是一段主进程代码,主进程负责创建一个浏览器实例来加载网页。每个创建的浏览器实例都在它自己的渲染进程内返回一个 Web 页面。当 BrowserWindow 实例销毁时,相应的渲染进程也会终止。主进程负责掌管所有的 Web 页面和它们相应的渲染进程。每个渲染进程都是相互独立的,它们只关心自己所运行的 Web 页面。


const electron = require('electron');const app = electron.app;const BrowserWindow = electron.BrowserWindow;
var window = null;
app.on('ready', function() { window = new BrowserWindow({width: 800, height: 600}); window.loadURL('https://microstrategy.com');});
复制代码


主进程还负责应用程序的生命周期(app 打开退出)和一些 app 事件的监听,同时负责系统底层 API 的调用。创建的渲染进程用来展示 HTML + CSS 技术编写的 Web 页面, 同时可以运行 JavaScript 实现交互,可以把渲染进程简单理解为 Chrome 上打开的一个浏览器进程。


<html>  <body>  <script>    const remote = require('electron').remote;    console.log(remote.app.getVersion());  </script>  </body></html>
复制代码


在渲染进程中是不允许调用原生 GUI 相关的 API,那是因为在网页中掌管原生 GUI 很危险,易造成内存泄露。如果你想在网页中进行 GUI 的操作,渲染进程必须向主进程传达请求,然后在主进程中完成操作。


Electron 封装了一系列自己的 API 可供主进程和渲染进程调用。可以通过如下方式获取:


const {app, BrowserWindow, ipcMain, ... } = require('electron'); // 仅主进程可用const {ipcRender, remote, ... } = require('electron'); // 仅渲染进程可用
复制代码


主进程和渲染进程均可直接调用 NodeJS 的 API:


node1.addEventListener('click', () => {   console.log(os.path.basename('xxxx');})
复制代码

进程通信

渲染进程如何向主进程发送消息

通信本质上基于 nodeJS 的事件基础类 Event-Emitter,ipcMain 和 ipcRender 都是该类的实例,通过事件模型需要的接口方法,采用了发布 / 订阅的方式来发送和监听消息。


异步方式:


import { ipcRender } from 'electron'; // 在渲染进程引入 ipcRender,它是 EventEmitter 的一个实例ipcRender.send('async', 'I am from webview'); // 可以异步发送
复制代码


同步方式:


import { ipcRender } from 'electron'; // 在渲染进程引入 ipcRenderipcRender.sendSync('sync', 'I am sync sent from webview'); // 同步方式
复制代码


通过同步方式发送会 block 整个渲染进程,直到主进程响应。


主进程会加载 ipcMain 来进行监听。


import { ipcMain } from 'electron'; // 在主进程引入 ipcMainipcMain.on('async', (event, info) {    console.log(info);});
复制代码


除此以外, electron 还提供了一种简单的方案(remote 模块)来实现渲染进程和主进程的通信。这样就可以不必显示地发送消息。


import { remote } from 'electron'; // 在渲染进程引入 remoteremote.mainProcessObject.invokeMethod(); // 调用主进程才有的方法});
复制代码

主进程如何向渲染进程发送消息

主进程通过找到渲染进程对应的 browserWindow 就可以发送消息。


constant window = BrowserWindow.fromId(global.id); // 通过 id 来进行对应window.webContents.send('msg', 'hello world');
复制代码


渲染进程监听:


ipcRender.on('msg', (event, info) => {    console.log(info)});
复制代码

渲染进程之间共享数据

一种可行的方案是在主进程实现消息的转发。还有比较简单的方案是通过浏览器实现的 HTML API,比如 localStorage, sessionStorage 或者 IndexedDB,或者通过主进程创建全局变量 sharedObject 来实现渲染进程的数据共享。


以上是一些 electron 技术的初步介绍,有兴趣的读者可以继续阅读详细的官方文档来深入学习。目前来看 electron 不能算一个年轻的开源项目, 还有不少新的桌面替代技术在涌现(比如 miniblink)。


作者介绍:


徐瑞青,高级软件工程师,毕业于鲁汶大学电子工程系。2014 年加入微策略,目前在数据 gateway 部门参与数据建模、清洗的开发工作,也参与过 Workstation 数据导入的早期开发。


本文转载自微信公众号:微策略 商业智能


2019-11-04 19:193968

评论 2 条评论

发布
用户头像
管理智能商务平台的大杀器 developer是什么东西?Java的话,RCP更流行吧?
2019-11-04 20:08
回复
没有更多了
发现更多内容

2022年最受工程师欢迎的10款抓包工具有哪些?不止Wireshark和Tcpdump哦!

wljslmz

Wireshark fiddler 网络技术 网络抓包 9月月更

大数据培训前景怎么样

小谷哥

谈谈我对云原生与软件供应链安全的思考

阿里巴巴中间件

阿里云 云原生 容器服务

一文带你认识AscendCL

华为云开发者联盟

人工智能 昇腾 企业号九月金秋榜

零基础如何参加大数据培训

小谷哥

在java培训中心怎样才能快速学习?

小谷哥

从云计算到函数计算

Serverless Devs

云计算 阿里云 AWS

Substrate技术及生态8月大事记 | 波卡发布新版本,XCM协议更新

One Block Community

区块链 技术 开发者 Substrate 更新

游戏技术加速数实融合,网易伏羲挖掘机器人首次曝光

网易伏羲

人工智能 机器学习 工程实践

跟我学Python图像处理丨何为图像的灰度非线性变换

华为云开发者联盟

Python 人工智能 图片处理 企业号九月金秋榜

学员参加前端培训哪里比较靠谱?

小谷哥

零基础学习java培训是否适合参加

小谷哥

软件测试 | 测试开发 | 测试开发基础 mvn test | 利用 Maven Surefire Plugin 做测试用例基础执行管理

测吧(北京)科技有限公司

maven

ArkID:开源IDaaS系统插件OAuth2轻松实现单点登录高效进行应用服务集成

龙归科技

oauth2.0 SSO Idaas

FinClip 8 月例行汇报,这个月干了啥

FinClip

首次公开到知乎爆火!基于SpringCloud+SpringBoot+Vue电子版项目实战教程,附完整源码

退休的汤姆

Java spring 程序员 面试题 阿里

阿里灵杰融合智能算力,全栈AI服务为探索者铺路

阿里云大数据AI技术

人工智能 大数据 企业号九月金秋榜

音视频开发进阶|第六讲:色彩和色彩空间·上篇

ZEGO即构

音视频开发 色彩 色彩空间

直播回顾|应用上容器的最佳实践技术沙龙

BoCloud博云

云计算 容器 云原生

二本4年Java经验,五面阿里(定薪45K)

退休的汤姆

Java 程序员 阿里 面经 秋招

DevOps 团队如何防御 API 攻击

SEAL安全

DevOps DevSecOps 软件供应链安全

分布式团队的高效站立会说明书 | Liga译文

LigaAI

高效工作 敏捷开发 开发团队 每日站会 企业号九月金秋榜

解锁云原生新场景 | 云原生加速云边端一体化发展

York

容器 云原生 边缘计算 边云协同 边缘云原生

基于阿里云Serverless函数计算开发的疫情数据统计推送机器人

Serverless Devs

EMQX +计算巢:构建云上物联网平台,轻松实现百万级设备连接

阿里云弹性计算

物联网 计算巢

公链开发功能详细分析

开发微hkkf5566

Aptos VS Sui,盘点两大 Move 系新公链的创新异同

TinTinLand

区块链 公链 编程语言‘ Move

利用GCC插件实现代码分析和安全审计

科技怪咖

Dubbo 3 StateRouter:下一代微服务高效流量路由

阿里巴巴中间件

阿里云 开源 微服务 dubbo 中间件

在线数据迁移,数字化时代的必修课 —— 京东云数据迁移实践

京东科技开发者

数据 数据迁移 上云 redis'

从零教你使用MindStudio进行Pytorch离线推理全流程

华为云开发者联盟

Python 人工智能 企业号九月金秋榜

桌面版应用程序的前世今生_大前端_徐瑞青_InfoQ精选文章