一文详解Electron 电源状态管理
目录
- Electron 电源相关模块
- 其中 powerMonitor 模块提供的接口
- powerSaveBlocker 模块提供的方法
- 空闲状态监控
- 电源状态监控
- 锁屏和解锁
- 休眠和唤醒
- 系统行为阻断
Electron 电源相关模块
在 Electron 中有两个模块是跟电源相关的:
- powerMonitor:用于获取电源相关信息,监听电源相关事件
- powerSaveBlocker:用于阻止系统进入睡眠状态
其中 powerMonitor 模块提供的接口
powerSaveBlocker 模块提供的方法
接下来详细介绍它们提供的能力,以及具体的应用场景:
空闲状态监控
getSystemIdleTime
方法可以获取当前用户的空闲时间,如果用户一直没有对电脑做任何操作,系统会认为当前用户处于空闲状态,并进行计时,这个 API 可以返回以秒为单位的空闲时间。示例代码如下:
const { powerMonitor } = require('electron') setInterval(() => { console.log(powerMonitor.getSystemIdleTime()) }, 3000)
如果一直没有操作,会每隔三秒打印:
3
6
9
12
15
18
如果中间用户做了任何操作,例如:
- 点击鼠标
- 滑动页面
- 按下键盘
- 碰触摸板
- 碰 TouchBar
- ……
那么系统会判定用户非空闲,然后将定时器重置,从零重新开始计时。与之相关的还有一个 API 是 getSystemIdleState(idleThreshold: number)
,可以通过传递一个时间阈值来判断用户的状态,有四种可能的值:
active
:用户处于活动状态idle
:用户处于空闲状态locked
:系统锁屏了unknown
:未知状态
电源状态监控
当电脑接入电源的时候,会触发 on-ac
事件,当拔掉电源,电池变成放电状态时,会触发 on-battery
事件。除了这两个事件之外,powerMonitor 还分别提供了一个 onBatteryPower
属性和一个 isOnBatteryPower
方法来判断是否使用电池供电,其实这两个东西是一样的,从 Electron 源码 lib/browser/api/power-monitor.ts
中可以看到仅仅是做了一个 getter 而已:
import { EventEmitter } from 'events'; import { app } from 'electron/main'; const { createPowerMonitor, getSystemIdleState, getSystemIdleTime, isOnBatteryPower } = process._linkedBinding('electron_browser_power_monitor'); class PowerMonitor extends EventEmitter { // 省略部分代码... getSystemIdleState (idleThreshold: number) { return getSystemIdleState(idleThreshold); } getSystemIdleTime () { return getSystemIdleTime(); } isOnBatteryPower () { return isOnBatteryPower(); } get onBatteryPower () { return this.isOnBatteryPower(); } }
锁屏和解锁
主进程可以监听到用户电脑的锁屏和解锁状态,这个 API 可以帮助我们做性能优化,例如页面中有个轮播图,每隔 5 秒就做一次轮播动画切换,消耗性能,如果此时用户都已经锁屏了,其实就没有必要再继续轮播了,可以用下面的代码通知渲染进程:
powerMonitor.on('lock-screen', () => { win.webContents.send('lock-screen') }) powerMonitor.on('unlock-screen', () => { win.webContents.send('unlock-screen') })
而在渲染进程的代码里可以这样写:
function Banner() { const [autoplay, setAutoplay] = useState(true) useEffect(() => { const lockScreen = () => setAutoplay(false) const unlockScreen = () => setAutoplay(true) ipcRenderer.on('lock-screen', lockScreen) ipcRenderer.on('unlock-screen', unlockScreen) return () => { ipcRenderer.removeListener('lock-screen', lockScreen) ipcRenderer.removeListener('unlock-screen', unlockScreen) } }, []) return ( <div className="banner-widget"> <div className="carousel"> <Slider autoplay={autoplay} autoplaySpeed={10000} arrows={false} > </Slider> </div> </div> ) }
这样就实现了:用户锁屏后不进行轮播,用户解锁后恢复轮播的效果。
休眠和唤醒
powerMonitor 模块也可以监听到系统休眠和唤醒事件,对应的 API 是:
powerMonitor.on('suspend', () => { console.log('系统休眠') }) powerMonitor.on('resume', () => { console.log('休眠唤醒') })
想要触发这个 API 的话,可以点击左上角的苹果 icon,在下拉菜单里面选择睡眠即可:
如果同时监听了锁屏和解锁,这些事件会同时触发,但是回调的顺序是不一定的,实际测试的时候发现下面两种情况都可能发生:
suspend resume lock-screen unlock-screen suspend lock-screen resume unlock-screen
其实第二次的顺序是符合直觉的,首先是「休眠」触发了「锁屏」,然后「休眠唤醒」触发了「屏幕解锁」。
系统行为阻断
在 Mac 和 Linux 平台下,powerMonitor 提供了 shutdown
事件来监听关机事件:
powerMonitor.on('shutdown', (e) => { e.preventDefault() })
如果在事件回调里面调用了 preventDefault
方法,其实是不能阻止系统关机的,但是可以延缓关机行为,从而让当前应用有足够的时间来做一些清理工作,当清理工作完成之后,要尽快调用 app.quit()
来退出程序。
操作系统在长时间没有收到用户操作事件后,会进入省电模式,显示器会被自动关闭,Electron 的 powerSaveBlocker
模块可以阻止系统进入睡眠模式,让操作系统和屏幕持续工作。示例代码如下:
const { powerSaveBlocker } = require('electron') // 阻止系统自动进入休眠状态 const id = powerSaveBlocker.start('prevent-display-sleep') // 指定 id 的 powerSaveBlocker 是否启动 console.log(powerSaveBlocker.isStarted(id)) setTimeout(()=>{ // 停止阻止行为 powerSaveBlocker.stop(id) console.log(powerSaveBlocker.isStarted(id)) }, 5000)
powerSaveBlocker
是一个独立的模块,它只提供了三个方法:
start
:阻止休眠stop
:停止阻止行为isStart
:查询阻止行为是否处于启用状态
其中start
方法需要传一个参数,有两个可选的值:
prevent-app-suspension
:保持系统活跃,但屏幕可以不亮prevent-display-sleep
:保持系统和屏幕活跃,屏幕要一直亮
举个例子,如果应用持续播放音频,可以用 prevent-app-suspension
,音频不需要屏幕常亮,如果应用持续播放视频或者PPT,就需要用 prevent-display-sleep
了,它们可以被同时调用,后者的优先级是高于前者的:
例如 A 调用了 prevent-app-suspension
,B 调用了 prevent-display-sleep
,那么 prevent-display-sleep
将生效,当 B 停止后 prevent-app-suspension
才生效。
以上就是一文详解Electron 电源状态管理的详细内容,更多关于Electron 电源状态管理的资料请关注我们其它相关文章!