一文詳解Electron 電源狀態(tài)管理
Electron 電源相關(guān)模塊
在 Electron 中有兩個模塊是跟電源相關(guān)的:
- powerMonitor:用于獲取電源相關(guān)信息,監(jiān)聽電源相關(guān)事件
- powerSaveBlocker:用于阻止系統(tǒng)進入睡眠狀態(tài)
其中 powerMonitor 模塊提供的接口

powerSaveBlocker 模塊提供的方法

接下來詳細介紹它們提供的能力,以及具體的應用場景:
空閑狀態(tài)監(jiān)控
getSystemIdleTime 方法可以獲取當前用戶的空閑時間,如果用戶一直沒有對電腦做任何操作,系統(tǒng)會認為當前用戶處于空閑狀態(tài),并進行計時,這個 API 可以返回以秒為單位的空閑時間。示例代碼如下:
const { powerMonitor } = require('electron')
setInterval(() => {
console.log(powerMonitor.getSystemIdleTime())
}, 3000)
如果一直沒有操作,會每隔三秒打?。?/p>
3
6
9
12
15
18
如果中間用戶做了任何操作,例如:
- 點擊鼠標
- 滑動頁面
- 按下鍵盤
- 碰觸摸板
- 碰 TouchBar
- ……
那么系統(tǒng)會判定用戶非空閑,然后將定時器重置,從零重新開始計時。與之相關(guān)的還有一個 API 是 getSystemIdleState(idleThreshold: number),可以通過傳遞一個時間閾值來判斷用戶的狀態(tài),有四種可能的值:
active:用戶處于活動狀態(tài)idle:用戶處于空閑狀態(tài)locked:系統(tǒng)鎖屏了unknown:未知狀態(tài)
電源狀態(tài)監(jiān)控
當電腦接入電源的時候,會觸發(fā) on-ac事件,當拔掉電源,電池變成放電狀態(tài)時,會觸發(fā) 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();
}
}
鎖屏和解鎖
主進程可以監(jiān)聽到用戶電腦的鎖屏和解鎖狀態(tài),這個 API 可以幫助我們做性能優(yōu)化,例如頁面中有個輪播圖,每隔 5 秒就做一次輪播動畫切換,消耗性能,如果此時用戶都已經(jīng)鎖屏了,其實就沒有必要再繼續(xù)輪播了,可以用下面的代碼通知渲染進程:
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>
)
}
這樣就實現(xiàn)了:用戶鎖屏后不進行輪播,用戶解鎖后恢復輪播的效果。
休眠和喚醒
powerMonitor 模塊也可以監(jiān)聽到系統(tǒng)休眠和喚醒事件,對應的 API 是:
powerMonitor.on('suspend', () => {
console.log('系統(tǒng)休眠')
})
powerMonitor.on('resume', () => {
console.log('休眠喚醒')
})
想要觸發(fā)這個 API 的話,可以點擊左上角的蘋果 icon,在下拉菜單里面選擇睡眠即可:

如果同時監(jiān)聽了鎖屏和解鎖,這些事件會同時觸發(fā),但是回調(diào)的順序是不一定的,實際測試的時候發(fā)現(xiàn)下面兩種情況都可能發(fā)生:
suspend resume lock-screen unlock-screen suspend lock-screen resume unlock-screen
其實第二次的順序是符合直覺的,首先是「休眠」觸發(fā)了「鎖屏」,然后「休眠喚醒」觸發(fā)了「屏幕解鎖」。
系統(tǒng)行為阻斷
在 Mac 和 Linux 平臺下,powerMonitor 提供了 shutdown 事件來監(jiān)聽關(guān)機事件:
powerMonitor.on('shutdown', (e) => {
e.preventDefault()
})
如果在事件回調(diào)里面調(diào)用了 preventDefault方法,其實是不能阻止系統(tǒng)關(guān)機的,但是可以延緩關(guān)機行為,從而讓當前應用有足夠的時間來做一些清理工作,當清理工作完成之后,要盡快調(diào)用 app.quit()來退出程序。
操作系統(tǒng)在長時間沒有收到用戶操作事件后,會進入省電模式,顯示器會被自動關(guān)閉,Electron 的 powerSaveBlocker 模塊可以阻止系統(tǒng)進入睡眠模式,讓操作系統(tǒng)和屏幕持續(xù)工作。示例代碼如下:
const { powerSaveBlocker } = require('electron')
// 阻止系統(tǒng)自動進入休眠狀態(tài)
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:查詢阻止行為是否處于啟用狀態(tài)
其中start方法需要傳一個參數(shù),有兩個可選的值:
prevent-app-suspension:保持系統(tǒng)活躍,但屏幕可以不亮prevent-display-sleep:保持系統(tǒng)和屏幕活躍,屏幕要一直亮
舉個例子,如果應用持續(xù)播放音頻,可以用 prevent-app-suspension,音頻不需要屏幕常亮,如果應用持續(xù)播放視頻或者PPT,就需要用 prevent-display-sleep 了,它們可以被同時調(diào)用,后者的優(yōu)先級是高于前者的:
例如 A 調(diào)用了 prevent-app-suspension,B 調(diào)用了 prevent-display-sleep,那么 prevent-display-sleep 將生效,當 B 停止后 prevent-app-suspension 才生效。
以上就是一文詳解Electron 電源狀態(tài)管理的詳細內(nèi)容,更多關(guān)于Electron 電源狀態(tài)管理的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
javascript實現(xiàn)類似于新浪微博搜索框彈出效果的方法
這篇文章主要介紹了javascript實現(xiàn)類似于新浪微博搜索框彈出效果的方法,涉及javascript彈出搜索框的相關(guān)實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-07-07
JS動態(tài)添加的div點擊跳轉(zhuǎn)到另一頁面實現(xiàn)代碼
這篇文章主要介紹了JS動態(tài)添加的div點擊跳轉(zhuǎn)到另一頁面實現(xiàn)代碼,需要的朋友可以參考下2017-09-09
詳細聊聊JavaScript是如何影響DOM樹構(gòu)建的
DOM (Document Object Model) 的全稱是文檔對象模型,它可以以一種獨立于平臺和語言的方式訪問和修改一個文檔的內(nèi)容和結(jié)構(gòu),這篇文章主要給大家介紹了關(guān)于JavaScript是如何影響DOM樹構(gòu)建的相關(guān)資料,需要的朋友可以參考下2021-08-08
JavaScript中字符串分割函數(shù)split用法實例
這篇文章主要介紹了JavaScript中字符串分割函數(shù)split用法,實例分析了javascript中split函數(shù)操作字符串的技巧,非常具有實用價值,需要的朋友可以參考下2015-04-04
vue?element?loading遮罩層添加按鈕功能實現(xiàn)
這篇文章主要介紹了vue?element?loading遮罩層添加按鈕功能實現(xiàn),通過實例代碼補充介紹了vue+elementui的this.$loading遮罩使用方法,需要的朋友可以參考下2024-03-03
javascript在事件監(jiān)聽方面的兼容性小結(jié)
javascript 在事件監(jiān)聽方面的兼容性總結(jié),注意是由于多個瀏覽器的不一致,導致大家在js書寫時需要考慮多個瀏覽器的兼容性。2010-04-04

