启动时窗体黑底,闪烁
const win = new BrowserWindow({
// ...
webPreferences: {
//这两句允许直接通信,无需channel
nodeIntegration: true,
contextIsolation: false,
},
show: false
})
// 关闭GPU加速,这个是关键
app.disableHardwareAcceleration();
// 官网搜索: 使用 ready-to-show 事件 有详细解释
win.once('ready-to-show', () => {
win.show();
})
//采用async
进程通信
渲染进程to主进程to渲染进程(to渲染进程可选)
禁止使用ipc发送大量数据,会阻塞主进程!!!
webContents.send方法只能单向通信,不采用。
方法一:同步
主进程关键代码:
ipcMain.on('render-to-main',(event, data) => { // data为接受到的消息
console.log("接收到render发送过来的消息:",data)
event.returnValue = 'pong' // 返回一个 'pong'
})
渲染进程关键代码:
const {ipcRenderer} = require('electron')
const setButton = document.getElementById('btn')
const txt = document.getElementById('changeTxt')
setButton.addEventListener('click', () => {
// 发送同步消息并获取返回值
const response = ipcRenderer.sendSync('render-to-main', 'ping');
// 直接使用返回值更新内容
txt.innerText = response.toString();
});
方法二:异步
主进程关键代码:
ipcMain.on('render-to-main-async', (event, data) => {
event.sender.send('main-to-render-async', 'pong'); // 发送异步响应给渲染进程
});
渲染进程关键代码:
const {ipcRenderer} = require('electron')
const setButton = document.getElementById('btn');
const txt = document.getElementById('changeTxt');
setButton.addEventListener('click', () => {
ipcRenderer.send('render-to-main-async', 'ping'); // 发送异步消息
});
ipcRenderer.on('main-to-render-async', (event, arg) => {
txt.innerText = arg.toString(); // 当收到消息时更新内容
});
主进程to渲染进程to主进程(to主进程可选)
异步方法:
主进程关键代码: 主进程使用webContents.send;ipcRenderer.send通常是网页间
// 监听渲染进程发来的“执行完毕”消息
ipcMain.on('execution-complete', (event, message) => {
console.log('渲染进程执行完毕:', message);
// 这里可以执行主进程后续的操作
});
// 假设在某个时机,主进程需要向渲染进程发送命令
setTimeout(() => {
win.webContents.send('update-title-input', '新的标题内容');
}, 2000); // 假设2秒后发送命令
渲染进程关键代码:
const { ipcRenderer } = require('electron');
document.addEventListener('DOMContentLoaded', (event) => {
const txt = document.getElementById('changeTxt');
// 监听主进程发来的“txt”命令
ipcRenderer.on('update-title-input', (event, newText) => {
txt.innerText = newText;
// 假设这里有一些异步操作需要完成,比如网络请求等
// 假设异步操作执行完毕后调用这个回复函数
executeSomeAsyncOperationAndReply();
});
function executeSomeAsyncOperationAndReply() {
// 模拟一些异步操作
setTimeout(() => {
// 操作执行完毕,向主进程发送“执行完毕”消息
ipcRenderer.send('execution-complete', '渲染进程操作已执行完毕');
}, 1000); // 假设异步操作需要1秒完成
}
});
渲染进程之间通信
方法一:使用主进程作为消息代理(推荐)
特点:可以掌控过滤进程之间的数据,提高安全性;理论上效率比不经过主进程,直接互相通信。
完整代码:
主进程:
const {app, ipcMain, BrowserWindow} = require('electron')
let win,win_app;
const createWindow = () => {
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
//这两句允许直接通信,无需channel
nodeIntegration: true,
contextIsolation: false,
},
show: false
})
win.loadFile('index.html')
win.once('ready-to-show', () => {
win.show()
})
}
const createWindow1 = () => {
win_app = new BrowserWindow({
width: 600,
height: 400,
webPreferences: {
//这两句允许直接通信,无需channel
nodeIntegration: true,
contextIsolation: false,
},
show: false
})
win_app.loadFile('app.html')
win_app.once('ready-to-show', () => {
win_app.show()
})
}
ipcMain.on('A send msg', (event ,arg) => {
// 假设在某个时机,主进程需要向渲染进程发送命令
setTimeout(() => {
win_app.webContents.send('main send msg', arg); //这里因为是转发,无需arg.toString()
}, 100); // 假设2秒后发送命令
})
// 关闭GPU加速,关键!!!
app.disableHardwareAcceleration()
app.whenReady().then(() => {
createWindow();
createWindow1();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
发起数据传输的渲染进程:render.js
const {ipcRenderer} = require('electron');
document.addEventListener('DOMContentLoaded', (event) => {
const txt = document.getElementById('changeTxt');
// 模拟一些异步操作
setTimeout(() => {
ipcRenderer.send('A send msg', "ping...");
txt.innerText = "数据发送到主进程完毕"
}, 2000); // 假设异步操作需要1秒完成
});
接收render.js发送来的被渲染进程:app.js
const { ipcRenderer } = require('electron');
document.addEventListener('DOMContentLoaded', (event) => {
const txt = document.getElementById('app');
ipcRenderer.on('main send msg', (event, arg) => {
txt.innerText = arg.toString(); //一定要toString
})
});
两个html代码:
//index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Hello World!</title>
</head>
<body>
<p id="changeTxt">main进程即将改变。。。</p>
<script src="./renderer.js"></script>
</body>
</html>
=====================================================================
//app.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Hello World!</title>
</head>
<body>
<p id="app">之前。。。。</p>
<script src="./app.js"></script>
</body>
</html>