当前位置: 首页 > news >正文

Electron[5] 渲染进程和主进程

1 进程

Electron里头的进程分为渲染进程和主进程。简单理解:

  1. main.js就是主进程
  2. 每个页面就是渲染进程
  3. 一个Electron应用仅有一个主进程,可以有多个渲染进程
    上面的这些概念很重要,不展开细讲。

2 进程职责

主进程是用来实现应用的基础功能,包括跟底层的系统交互等。渲染进程是用来实现具体每个页面的功能。
那么当渲染进程需要跟系统底层进行交互的时候,怎么处理呢?目前有两种方式:

  1. 在渲染进程里头直接引用支持跟底层进行交互的包,然后直接实现跟底层的交互(十分不推荐)
  2. 渲染进程将事件委托给主进程,让主进程来完成。(推荐)
  3. 事件委托是通过事件监听和触发来实现的。

3 渲染进程与Native API

虽然上面说了,不建议渲染进程直接调用Native API,但是还是要说下,渲染进程如何实现直接调用底层API。

之所以不建议渲染进程直接调用Native API是因为,渲染进程调用原生能力,其实是从主进程同步过来的,那么在应用的使用过程,就要不断的实现主进程和渲染进程之间的原生能力载体的状态同步,这个同步是十分耗费宿主机资源的。

3.1保存文件

下面的案例是讲解下如何通过渲染进程直接调用原生API。

3.1.1 渲染进程页面

先用h5画出包含有一个文本框和用来保存的按钮。
源码如下:

<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>electron从入门到精通</title>
</head>
<body> <button type="button" id="saveBtn">保存文件</button><textarea id="textArea" style="position:absolute;top:60px;bottom:0;left:0;right:0;"></textarea>
<script src="./test.js"></script>
</body>
</html>

然后test.js的源码如下:

const { dialog } = require('@electron/remote')
//引入fs模块
var fs = require('fs')
//获取文本框的dom 
var textAreaDom = document.querySelector('#textArea')
var saveBtn = document.getElementById('saveBtn')// 文件保存路径,第一保存后,就缓存起来
var currentPath = null
saveBtn.addEventListener('click',function(){if (currentPath) {writeFile(currentPath)} else {// 调用native api实现文件保存dialog.showSaveDialog({properties:['showOverwriteConfirmation']}).then(({canceled,filePath})=>{if (!canceled) {writeFile(filePath)currentPath = filePath}})}})
function writeFile(path,){fs.writeFileSync(path, textAreaDom.value)}

到这边要停下来下,缓一缓捋一捋。
首先,我们需要在渲染进程里头引用node的包,fs包,其次,还用到了remote的依赖包。因此还需要做如下操作:

  • 安装@electron/remote,版本:2.0.12
npm install @electron/remote@2.0.12
  • 调整渲染进程窗口的创建配置。创建窗口是在main.js里实现的,下面直接附上整个main.js的文件:
		// main.jsconst { app, BrowserWindow} = require('electron')const path = require('path')// *************************1.引入remote模块******************************const remote = require("@electron/remote/main");remote.initialize();function createWindow () {const mainWindow = new BrowserWindow({width: 800,height: 600,webPreferences:{//  渲染进程 开启node模块,使得JS中可以使用node的modelnodeIntegration:true,// 开启 remote 模块enableBlinkFeatures:true,// 控制上下文隔离contextIsolation:false,//由于安全问题,remote模块默认关闭enableRemoteModule: true,//开启remote模块//关闭web权限检查,允许跨域webSecurity: false,}})mainWindow.loadFile('./src/index.html')// 默认打开调试工具mainWindow.webContents.openDevTools()// ********2.启用remote模块,渲染进程就可以使用主程序模块********************remote.enable(mainWindow.webContents);  }app.whenReady().then(() => {createWindow()app.on('activate', () => {if (BrowserWindow.getAllWindows().length === 0) {createWindow()}})})app.on('window-all-closed', () => {if (process.platform !== 'darwin') {app.quit()}})

至此,源码分享就结束了。

4 源码解释

4.1 test.js和Electron的原生能力

上面主要麻烦的就是test.js里头的dialog的使用。这个调用的是原生能力的弹窗,其实像原生能力的使用,不知道都觉得很麻烦,但是,如果知道了,就不难,下面附上原生能力的工具字典:
app | Electron

4.2 remote模块

不同版本的Electron使用的remote是不一样的,main.js里头关于remote的配置,以及渲染进程里头的remote的引用都是跟版本挂钩了,大家如果一意孤行还要用使用不推荐的方式来使用原生能力的话,那么配置就按照上面的来做即可了。

http://www.lryc.cn/news/257140.html

相关文章:

  • 基于Java SSM框架实现大学生校园兼职系统项目【项目源码+论文说明】
  • Codeforces Round 913 (Div. 3) A~E
  • 反序列化 [网鼎杯 2020 朱雀组]phpweb 1
  • Java 何时会触发一个类的初始化
  • 我的记事本
  • GO设计模式——4、单例模式(创建型)
  • 我对迁移学习的一点理解——领域适应(系列3)
  • 【openssl】RSA 生成公钥私钥 |通过私钥获取公钥
  • MongoDB的删除文档、查询文档语句
  • Rust编程语言入门教程(三)-trait
  • LeetCode-1566. 重复至少 K 次且长度为 M 的模式【数组 枚举】
  • QT5.4.1无法打开文件
  • 【1day】金和OA某接口存在未授权访问漏洞
  • 使用Rust 构建C 组件
  • AI:大模型技术
  • 揭开WPF里面XAML可以通过http引入命名空间的神秘面纱
  • 什么是高防IP,高防IP该如何选择。
  • Linux 进程
  • Docker部署开源分布式任务调度平台DolphinScheduler并实现远程访问办公
  • SQL语言重温
  • Java学习手册——第五篇数据类型
  • 机器学习算法性能评估常用指标总结
  • java面试题-ArrayList 和 LinkedList 的区别是什么
  • k8s中部署基于nfs的StorageClass
  • c语言一维数组总结详解
  • Redis 持久化 —— 超详细操作演示!
  • 使用Java实现桶排序算法
  • 5.题目:编号1624 小蓝吃糖果
  • 基于SpringBoot+thymeleaf协同过滤算法山河旅游推荐系统(Java毕业设计)
  • TypeScript 之 console的使用