這篇筆記主要解決的問題是Electron的主進程與渲染進程之間的通信.
使用ipcMain和ipcRenderer
// 來自官方的示例 const {ipcMain} = require('electron') ipcMain.on('asynchronous-message', (event, arg) => { console.log(arg) // prints "ping" event.sender.send('asynchronous-reply', 'pong') }) ipcMain.on('synchronous-message', (event, arg) => { console.log(arg) // prints "ping" event.returnValue = 'pong' })
要點:
- 渲染進程可以通過
ipcRenderer
向主進程發送消息 - 主進程通過
ipcMain
監聽來自渲染進程的消息. 並根據消息類型執行不同的操作 - 主進程的回調方法包含
event
和arg
兩個參數.arg
對象中保存了渲染進程傳遞的參數. 通過event.sender
對象,主進程可以直接向渲染進程發送返回消息. 如果主進程執行的同步方法,還可以通過設置event.returnValue
來獲取返回值.
使用 electron.remote 模塊
在渲染進程中,可以通過const {remote} = require('electron')
來獲取到remote對象. 通過這個對象可以允許渲染進程訪問主進程的模塊.
const {BrowserWindow} = require('electron').remote; let win = new BrowserWindow({width: 800, height: 600}); win.loadURL('https://xxx.com');
同樣的,我們也可以通過remote
對象訪問到app
對象。這樣我們就可以訪問到我們在主進程中掛載到electron.app
對象上的方法。
// 主進程 const { app } = require('electron'); const utils = require('./utils'); app.utils = utils; // 將在 Electron 層實現的接口綁定到 app 上
// 渲染進程 const { remote } = require('electron'); function() { // remote.app.utils 對象與主進程中的utils對象是一樣的。 remote.app.utils.test(); }
要點:
通過remote
對象,我們可以不必發送進程間消息來進行通信。但實際上,我們在調用遠程對象的方法、函數或者通過遠程構造函數創建一個新的對象,實際上都是在發送一個同步的進程間消息(官方文檔 上說這類似於JAVA
中的RMI
)。
也就是說,remote
方法只是不用讓我們顯式的寫發送進程間的消息的方法而已。在上面通過remote
模塊創建BrowserWindow
的例子里。我們在渲染進程中創建的BrowserWindow
對象其實並不在我們的渲染進程中,它只是讓主進程創建了一個BrowserWindow
對象,並返回了這個相對應的遠程對象給了渲染進程。