Electron App 模块
介绍
app 模块是 Electron 应用程序的核心,它负责管理整个应用程序的生命周期。该模块只能在 主进程 中使用
核心功能
- 生命周期管理: 控制应用的启动、退出、以及在不同阶段触发的事件
- 系统集成: 与操作系统进行交互,例如修改 Dock 栏、设置应用名称、处理协议链接等
- 路径管理: 获取系统定义的各种路径,如用户数据目录、临时文件目录等
- 应用信息: 获取应用名称、版本号等信息
主要功能和用途
- 创建和管理浏览器窗口 (
BrowserWindow) - 监听并响应应用的生命周期事件。
- 控制应用的菜单、Dock 栏、任务栏等
- 处理应用的启动参数和协议
- 管理应用的基本信息和设置
核心 API 详解
生命周期事件
app 模块通过触发一系列事件来让您有机会响应应用程序状态的变化
ready: 当 Electron 完成初始化时触发。这是创建浏览器窗口等操作最安全的时机。也可以使用app.whenReady(),它返回一个 Promise,在应用就绪时 resolvewindow-all-closed: 当所有的窗口都被关闭时触发before-quit: 在应用程序开始关闭窗口之前触发。可以通过event.preventDefault()来阻止应用退出will-quit: 在所有窗口都已关闭,应用即将退出时触发。同样可以通过event.preventDefault()阻止退出quit: 在应用退出时触发activate(macOS): 当应用被激活时触发,例如点击 Dock 图标
示例:
js
const { app, BrowserWindow } = require("electron")
app.on("ready", () => {
const win = new BrowserWindow()
win.loadFile("index.html")
})
app.on("window-all-closed", () => {
// 在 macOS 上,除非用户用 Cmd + Q 确定退出,
// 否则应用在没有窗口的情况下仍会保持活跃。
if (process.platform !== "darwin") {
app.quit()
}
})
app.on("before-quit", (event) => {
// 在这里可以执行一些清理工作,例如保存用户数据
// 如果有未完成的任务,可以阻止应用退出
if (hasUnsavedChanges) {
event.preventDefault()
// 提示用户保存
}
})
app.on("activate", () => {
// 在 macOS 上,当点击 Dock 图标并且没有其他窗口打开时,
// 通常在应用程序中重新创建一个窗口。
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})应用程序控制方法
-
app.quit(): 尝试关闭所有窗口并退出应用程序 -
app.exit(exitCode): 强制退出应用,exitCode默认为 0。这会立即终止应用,不会触发before-quit和will-quit事件 -
app.relaunch(): 重新启动当前应用 -
app.focus(): 在 Windows 和 macOS 上,将应用程序的第一个窗口置于前台 -
app.hide()(macOS): 隐藏所有应用窗口 -
app.show()(macOS): 显示所有被隐藏的应用窗口
路径管理
-
app.getPath(name): 获取与name关联的系统目录或文件的路径。常用的name包括:home: 用户的主目录appData: 当前用户的应用数据目录userData: 存储应用配置文件的目录temp: 临时文件夹desktop: 当前用户的桌面目录documents: "我的文档" 目录downloads: 下载目录exe: 当前可执行文件的路径module:libchromiumcontent库的路径
javascriptconst path = require("path") const dbPath = path.join(app.getPath("userData"), "user-data.db") -
app.setPath(name, path): 设置name对应的路径。只能在ready事件触发前调用
其他重要方法
app.getName(): 获取当前应用的名称app.setName(name): 设置当前应用的名称app.getVersion(): 获取应用的版本号app.getLocale(): 获取当前应用的语言环境app.isReady(): 返回一个布尔值,判断ready事件是否已触发app.addRecentDocument(path)(Windows & macOS): 将路径添加到最近使用的文档列表中app.clearRecentDocuments()(Windows & macOS): 清空最近使用的文档列表
使用示例
基础初始化代码
这是一个典型的 Electron 主进程文件 (main.js) 的结构:
javascript
const { app, BrowserWindow } = require("electron")
const path = require("path")
function createWindow() {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, "preload.js")
}
})
mainWindow.loadFile("index.html")
}
app.whenReady().then(() => {
createWindow()
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit()
}
})处理单例应用
确保应用只有一个实例在运行
javascript
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
} else {
app.on("second-instance", (event, commandLine, workingDirectory) => {
// 当运行第二个实例时,聚焦到主窗口
if (myWindow) {
if (myWindow.isMinimized()) myWindow.restore()
myWindow.focus()
}
})
// ... 创建窗口等
}注意事项
平台差异
window-all-closed: 在 macOS (darwin) 上,关闭所有窗口通常不会退出应用。应用会保持在 Dock 栏中,直到用户显式退出 (Cmd + Q)activate: 这个事件只在 macOS 上触发- 菜单和 Dock/任务栏: 不同平台有不同的 UI 约定,需要为不同平台编写特定的代码来处理
常见问题解决方案
- API 在
ready事件前调用: 大多数app模块的 API 只能在ready事件触发后使用。如果过早调用,可能会导致错误或无效果 - 黑屏/白屏: 如果在
ready事件后没有正确创建窗口或加载内容,应用可能会显示一个空白窗口。确保窗口创建和内容加载逻辑正确
性能优化建议
- 延迟加载模块: 只有在需要时才
require模块,可以加快应用的启动速度 - 使用
whenReady(): 相比于on('ready', ...),app.whenReady()提供了更现代的 Promise-based API,代码更清晰
相关模块链接
- BrowserWindow: 创建和控制应用窗口
- ipcMain: 在主进程和渲染进程之间进行异步通信
- Menu: 创建原生应用菜单和上下文菜单
- dialog: 显示用于打开/保存文件、警告等的原生系统对话框