Electron App 速查表:生命周期事件、方法、平台差异

0 阅读5分钟

Electron App API 知识点总结

目录


1. App 模块概述

app 模块用于控制应用程序的事件生命周期。它是主进程模块

基本使用

const { app } = require('electron')

app.on('window-all-closed', () => {
  app.quit()
})

2. 应用程序生命周期事件

事件触发顺序

┌─────────────────────────────────────────────┐
│  will-finish-launching                      │
│      ↓                                      │
│  ready  ← 最重要的!应用入口                 │
│      ↓                                      │
│  [应用运行中]                                │
│      ↓                                      │
│  window-all-closed (可选)                   │
│      ↓                                      │
│  before-quit                                │
│      ↓                                      │
│  will-quit                                  │
│      ↓                                      │
│  quit  ← 应用退出                          │
└─────────────────────────────────────────────┘

2.1 will-finish-launching

应用程序完成基础启动时触发。

  • Windows/Linux:与 ready 事件相同
  • macOS:相当于 applicationWillFinishLaunching
  • 建议:大部分逻辑应在 ready 事件中处理

2.2 ready ⭐最重要

Electron 完成初始化时触发一次。

app.on('ready', (event, launchInfo) => {
  console.log('应用已就绪')
  // 创建窗口、初始化应用等
})

// 替代写法:返回 Promise
app.whenReady().then(() => {
  // 应用已就绪
})

2.3 window-all-closed

所有窗口关闭时触发。

app.on('window-all-closed', () => {
  // macOS 外,退出应用
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

2.4 before-quit

关闭窗口前触发。调用 event.preventDefault() 可阻止退出。

2.5 will-quit

所有窗口关闭后、应用程序退出前触发。

2.6 quit

应用程序退出时触发。

⚠️ Windows 注意:如果应用程序因系统关机/重启而关闭,before-quitwill-quitquit 事件不会触发。


3. macOS 特有事件

3.1 activate

应用被激活时触发。

触发场景

  • 首次启动应用
  • 点击 Dock 或任务栏图标
  • 应用已在运行时尝试重新激活
app.on('activate', (event, hasVisibleWindows) => {
  if (!hasVisibleWindows) {
    // 创建新窗口
    createWindow()
  }
})

3.2 did-become-active

每次程序被激活前触发(不仅限于 Dock 点击)。

3.3 open-file ⭐重要

用户想要在应用中打开文件时触发。

// 必须在 ready 事件前监听!
app.on('open-file', (event, path) => {
  event.preventDefault()
  console.log('打开文件:', path)
})

3.4 open-url

用户通过 URL scheme 打开应用时触发。

app.on('open-url', (event, url) => {
  event.preventDefault()
  console.log('打开 URL:', url)
})

⚠️ 重要:必须在 ready 事件前注册监听器!

3.5 Handoff 相关事件(macOS)

事件名说明
will-continue-activity跨设备活动恢复前
continue-activity跨设备活动恢复时
continue-activity-error跨设备活动恢复失败
activity-was-continued本设备活动在其他设备恢复
update-activity-state活动状态更新

3.6 其他 macOS 事件

事件名说明
new-window-for-tab点击原生新标签按钮
did-rele-active应用长时间非激活状态

4. 窗口相关事件

4.1 browser-window-created

当新的 BrowserWindow 被创建时触发。

app.on('browser-window-created', (event, window) => {
  console.log('新窗口创建')
})

4.2 browser-window-focus

窗口获得焦点时触发。

4.3 browser-window-blur

窗口失去焦点时触发。

4.4 web-contents-created

当新的 WebContents 被创建时触发。


5. 安全与认证事件

5.1 certificate-error

证书验证失败时触发。可用于信任自签名证书。

app.on('certificate-error', (event, webContents, url, error, certificate, callback) => {
  if (url === 'https://example.com') {
    event.preventDefault()
    callback(true)  // 信任该证书
  } else {
    callback(false)
  }
})

5.2 select-client-certificate

客户端证书请求时触发。

app.on('select-client-certificate', (event, webContents, url, list, callback) => {
  event.preventDefault()
  callback(list[0])  // 选择第一个证书
})

5.3 login

基本认证时触发。

app.on('login', (event, webContents, details, authInfo, callback) => {
  event.preventDefault()
  callback('username', 'password')
})

6. 进程相关事件

6.1 render-process-gone

渲染器进程意外消失时触发。

app.on('render-process-gone', (event, webContents, details) => {
  if (details.reason === 'crashed') {
    console.log('渲染进程崩溃')
  }
})

6.2 child-process-gone

子进程意外消失时触发。

reason 值说明
clean-exit正常退出(退出码 0)
abnormal-exit非零退出码退出
killed被 SIGTERM 或外部杀死
crashed进程崩溃
oom内存不足
launch-failed启动失败
integrity-failure代码完整性检查失败

6.3 second-instance

第二个应用实例启动时触发。

const gotTheLock = app.requestSingleInstanceLock()

if (!gotTheLock) {
  app.quit()
} else {
  app.on('second-instance', (event, argv, workingDirectory, additionalData) => {
    // 将第二个实例的窗口聚焦
    if (mainWindow) {
      if (mainWindow.isMinimized()) mainWindow.restore()
      mainWindow.focus()
    }
  })
}

6.4 session-created

创建新 session 时触发。

app.on('session-created', (session) => {
  console.log('新 session 创建')
})

7. 应用方法

7.1 退出应用

方法说明触发事件
app.quit()尝试关闭所有窗口并退出before-quit → will-quit → quit
app.exit(exitCode)立即退出不触发任何退出事件
// 优雅退出
app.quit()

// 强制退出(不触发 before-quit)
app.exit(1)

7.2 重启应用

app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) })
app.exit(0)

7.3 应用状态检查

app.isReady()      // 是否已就绪
app.whenReady()    // 返回 Promise

7.4 macOS 应用激活

app.hide()         // 隐藏所有窗口
app.show()         // 显示隐藏的窗口
app.isHidden()     // 检查是否隐藏
app.focus()        // 聚焦应用

8. 应用信息管理

8.1 获取应用路径

app.getAppPath()              // 当前应用程序目录
app.getPath('home')           // 用户主目录
app.getPath('appData')        // 应用数据目录
app.getPath('userData')       // 用户配置目录
app.getPath('logs')           // 日志目录
app.getPath('desktop')         // 桌面目录
app.getPath('documents')       // 文档目录
app.getPath('downloads')       // 下载目录
app.getPath('temp')            // 临时目录

8.2 设置日志路径

app.setAppLogsPath('/custom/path')  // 自定义日志路径

8.3 应用信息

app.getName()              // 应用名称
app.getVersion()            // 应用版本
app.getLocale()            // 当前语言
app.getLocaleCountryCode() // 国家代码

最佳实践总结

✅ 推荐写法

const { app, BrowserWindow } = require('electron')

let mainWindow

function createWindow() {
  mainWindow = new BrowserWindow({ width: 1200, height: 800 })
  mainWindow.loadURL('https://example.com')
}

// 等待应用就绪
app.whenReady().then(() => {
  createWindow()
  
  // macOS:点击 Dock 图标时如果没有窗口则创建
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    }
  })
})

// 关闭所有窗口时退出(非 macOS)
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

// 确保单实例
const gotLock = app.requestSingleInstanceLock()
if (!gotLock) {
  app.quit()
} else {
  app.on('second-instance', () => {
    if (mainWindow) {
      if (mainWindow.isMinimized()) mainWindow.restore()
      mainWindow.focus()
    }
  })
}

❌ 避免做法

  1. 不要在 ready 事件前使用需要初始化的 API
  2. macOS 应用不要在 window-all-closed 中直接 quit
  3. 处理文件打开要在应用启动前注册监听器
  4. Windows 下注意关机不会触发退出事件

事件速查表

事件跨平台macOS说明
will-finish-launching基础启动完成
ready应用就绪(最重要)
window-all-closed所有窗口关闭
before-quit退出前
will-quit即将退出
quit应用退出
activate应用激活
open-file打开文件
open-url通过 URL 打开
browser-window-created窗口创建
certificate-error证书错误
login认证
render-process-gone渲染进程消失
second-instance第二个实例
session-createdSession 创建

文档基于 Electron v28+ App API 编写