主进程(Main Process)
正如之前所提,Electron有两大进程:主进程(Main Process)和渲染进程(Renderer Process)。在这个示例程序中,主进程代码就在main.js
文件中。
Note
通常将主进程文件命名为main.js,这样表示Node从这里启动应用的主进程。当你的项目代码重构目录结构后,必须在package.json中将主进程文件重新指定。
main.js
的基础代码中有许多有用的注释,大致如下:
const electron = require('electron')
// Module to control application life.
const app = electron.app
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow
const path = require('path')
const url = require('url')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow() {
// Create the browser window.
mainWindow = new BrowserWindow({ width: 800, height: 600 })
// and load the index.html of the app.
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
// Open the DevTools.
mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
最开始的代码用来获取应用所需模块:
const electron = require('electron')
// Module to control application life.
const app = electron.app
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow
const path = require('path')
const url = require('url')
electron
正是Electron模块,提供了Electron的API和Node扩展。
app
调用Electron的API来控制应用的生命周期,稍后的代码会展示其用法。
BrowserWindow
控制Electron的渲染进程。我们将会用它创建一个Chromium实例来生成应用的UI。
path
和url
是Electron调用的Node API,这些是能供任何Electron程序调用的Node API的一部分。path
用来处理文件和目录操作,url
用来创建URL。
接下来的代码穿插着注释讲述如下:
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
Note
如果你启动应用后窗口却不出现,很可能是因为主进程没有引用mainWindow。这种情况也会导致应用的其他窗口无法创建。
然后是创建主窗口的方法createWindow
:
function createWindow() {
// Create the browser window.
mainWindow = new BrowserWindow({ width: 800, height: 600 })
// and load the index.html of the app.
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
// Open the DevTools.
mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
createWindow
方法的流程如下:
* 创建一个浏览器窗口(BrowserWindow),传入一个描述窗口尺寸的对象。本例中窗口高800像素,宽600像素。
* 使用path
和url
连接index.html
模块加载窗口。index.html
文件是渲染进程的开始点。
* mainWindow.webContents.openDevTools()
打开Chromium的开发者工具(Developer Tools)。开发者工具对于调试渲染进程十分有用。
* 监听窗口实例的closed
事件。此处注释描述如何管理多个窗口。这个方法仅仅是将你的窗口实例引用置为null,在未来将会加入更多代码。
代码最后的部分是app
的监听器(listener),用来控制窗口何时创建、应用何时退出。
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
app
实例监听三个事件:ready
、window-all-closed
和activate
。
当收到ready
事件后,调用上面讲过的createWindow
方法。
如注释所述,由于在Mac OS X平台下用户可以关闭程序所有的窗口而不退出程序,而在Windows和Linux却并非如此,window-all-closed
用来关闭非Max OS X平台的程序。
值得注意的是,我们用了Node API提供的模块process
。在本例中process.platform
在Max OS X平台会返回darwin
,而在Windows平台会返回win32
。即时在64位Windows平台下process.platform
也会返回win32
,用process.arch
(表示架构:Architecture)会返回x64
。
由于用户能在Max OS X平台下启动一个应用而不打开窗口,activate
事件被触发时会创建新窗口。这里没有判断当前系统类型,因为创建窗口的条件为:activate
事件被触发,并且主窗口为空(mainWindow === null),这些条件只会在Max OS X平台满足。
在main.js
文件的最底端注释提示我们,可以在此为主进程添加其他代码,或者引用外部文件提高代码整洁度。