主进程和渲染器进程
Electron 有两种进程:主进程和渲染进程。
- 主进程通过创建 BrowserWindow 实例来
创建
网页。 每一个BrowserWindow
实例在其渲染过程中运行网页, 当一个BrowserWindow
实例被销毁时,对应的渲染过程也会被终止。 - 主进程 管理 所有网页及其对应的渲染进程。
- 渲染进程只能管理相应的网页, 一个渲染进程的崩溃不会影响其他渲染进程。
- 渲染进程通过 IPC 与主进程通信在网在页上执行 GUI 操作。 出于安全和可能的资源泄漏考虑,直接从渲染器进程中调用与本地 GUI 有关的 API 受到限制。
进程之间的通信可以通过 Inter-Process Communication (IPC) 模块进行:ipcMain 和 ipcRenderer
若要创建一个窗口,请调用 BrowserWindow
类,但只能在主进程中使用 ():
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
若要从渲染进程调用主进程,请使用 IPC 模块: 例如净化窗口模式下自定义关闭窗口功能
1. 首先由主进程向渲染进程发送消息,告诉它窗口的 id (开启了多个渲染进程);
('ready-to-show', () => {
('init_win_id', );
()
});
2. 在渲染进程接收 winid, 并在关闭窗口时发送给主进程
//渲染进程监听init_win_id事件(自定义),将winid赋给全局变量winid
let winid = '';
require('electron').('init_win_id', (event, message) => {
winid = message;
})
// 关闭窗体
function closex(){
//渲染进程里把窗口id发给主进程
const { ipcRenderer } = require('electron')
('close_window', winid);
}
3. 在主进程中接收需要关闭的渲染进程
// 主进程获取winid关闭窗体
('close_window', (event, arg) => {
//()单个窗口可以直接()
//();
// 1、接收渲染进程发来的窗口id
let winid = arg;
(winid);
// 2、通过id找到对应的BrowserWindow对象(win、win22),调用这个对象的close()关闭对应的窗口
(winid).close();
})
主进程创建并关闭多个渲染进程
主脚本指定了运行主进程的 Electron 应用程序的入口 , 通常是 文件 , Electron 应用程序只能有一个主进程。
1. 为了管理应用程序的生命周期事件以及创建和控制浏览器窗口,需要从 electron 包导入了 app 和 BrowserWindow 模块,
const { app, BrowserWindow } = require('electron')
2. 定义一个创建新的浏览窗口的函数并将 nodeIntegration 设置为 true,将 文件加载到窗口中,
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
//注意: 设置 nodeIntegration 选项为 true 表示渲染过程中可以访问 API
nodeIntegration: true
}
})
('')
}
3. 调用 createWindow
方法,在 electron app 第一次被初始化时创建一个新的窗口
().then(createWindow)
4. 添加一个新的侦听器,当应用程序不再有任何打开窗口时试图退出。 由于操作系统的 窗口管理行为 ,此监听器在 macOS 上是禁止操作的。
('window-all-closed', () => {
if ( !== 'darwin') {
()
}
})
5. 添加一个新的侦听器,只有当应用程序激活后没有可见窗口时,才能创建新的浏览器窗口。 例如,在首次启动应用程序后或重启运行中的应用程序。
('activate', () => {
if (().length === 0) {
createWindow()
}
})
-------------------------------------------------------------------------------------- 创建多个窗口 -----------------------
若要创建一个窗口,请调用 BrowserWindow 类,再次创建一个 BrowserWindow 实例,但只能在主进程中使用:我们可以修改以上代码
const {
app,
BrowserWindow
} = require('electron')
//全局访问
let win
let win22
function createWindow() {
win = new BrowserWindow({
width: 800,
height: 600,
frame: false,
webPreferences: {
nodeIntegration: true
}
})
('')
('ready-to-show', () => {
()
})
win22 = new BrowserWindow({
width: 800,
height: 600,
frame: false,
webPreferences: {
nodeIntegration: true
}
})
('')
('ready-to-show', () => {
()
})
}
().then(createWindow)
('window-all-closed', () => {
if ( !== 'darwin') {
()
}
})
('activate', () => {
if (().length === 0) {
createWindow()
}
})
BrowserWindow 对象可调用的成员有很多,比如 id 获取唯一窗口 id,close () 成员方法关闭窗口等
-------------------------------------------------------------------------------------- 删除多个窗口 -----------------------
在主进程中将多个窗口的 id 分别发送给各自的渲染窗口,主 -> 渲染通讯 使用 BrowserWindow 实例属性 webContents 的 send () 方法实现
const {
app,
BrowserWindow
} = require('electron')
let win
let win22
function createWindow() {
win = new BrowserWindow({
width: 800,
height: 600,
frame: false,
webPreferences: {
nodeIntegration: true
}
})
('')
('ready-to-show', () => {
('init_win_id', );
()
})
win22 = new BrowserWindow({
width: 800,
height: 600,
frame: false,
webPreferences: {
nodeIntegration: true
}
})
('')
('ready-to-show', () => {
('init_win_id', );
()
})
}
().then(createWindow)
('window-all-closed', () => {
if ( !== 'darwin') {
()
}
})
('activate', () => {
if (().length === 0) {
createWindow()
}
})
在各自的渲染窗口中获取 winid. 并在关闭窗口事件中将之传给主进程,由主进程关闭渲染进程
以下是主进程获取到需要关闭的窗口 id 以后需要执行的操作
const {
ipcMain
} = require('electron')
('close_window', (event, arg) => {
let winid;
winid = arg
(winid);
//根据id获取 BrowserWindow实例,然后调用close()方法
(winid).close();
})
关闭一个渲染进程,开启另一个渲染进程
1. 将登录页面的窗口 id 发给主进程
let winid = '';
require('electron').('init_win_id', (event, message) => {
winid = message;
})
function dologin()
{
//登录成功以后
const {ipcRenderer} = require('electron')
('dologin',winid)//winid是主进程在初始化登录页面时传过来的
}
接着在主进程中接收 winid, 关闭登录窗口,显示 qq 聊天界面
const {
app,
BrowserWindow
} = require('electron')
var win;
let winQQList;
function createWindow() {
win = new BrowserWindow({
width: 1200,
height: 800,
frame: false,
show: false,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
}
});
('');
('ready-to-show', () => {
// 向渲染进程发消息,告诉它窗口的id
= ;
('init_win_id', );
()
});
}
('dologin', () => {
let winid = arg
winQQList = new BrowserWindow({
width: 300,
height: 800,
frame: false,
show: false,
webPreference: {
nodeIntegration: true
}
})
('')
('ready-to-show', () => {
('init_win_id', );
()
})
})
转自主进程创建并关闭多个渲染进程 - imzchloe的个人空间 - OSCHINA - 中文开源技术交流社区