本文主要講解上一章節提到的主進程與渲染進程的概念,以及它們是如何被使用的
javascript
若是對文章的內容有任何疑問或吐槽,請直接在下方評論,你們共同窗習和改進
html
閱讀時間:約4min
java
咱們來回顧一下,程序目錄結構章節中所給出的基本目錄結構node
app----------------------------應用程序代碼目錄
├─main.js----------------------程序啓動入口,主進程
├─common-----------------------通用模塊
├─log--------------------------日誌模塊
├─config-----------------------配置模塊
├─ipc--------------------------進程間模塊
├─appNetwork-------------------應用通訊模塊
└─browserWindows---------------窗口管理,渲染進程
├─components---------------通用組件模塊
├─store--------------------數據共享模塊
├─statics------------------靜態資源模塊
└─src----------------------窗口業務模塊
├─窗口A----------------窗口
└─窗口B----------------窗口
複製代碼
在上面的目錄結構中,main.js
就是咱們所說的主進程。而經過browserWindows
目錄下窗口文件建立的進程,咱們稱之爲渲染進程。渲染進程須要經過主進程來建立,並被主進程所管理。這裏你們可能會有疑問了,什麼是進程?爲何要分主進程和渲染進程呢?web
計算機進程相關的知識在搜索引擎中能夠搜到不少,咱們這裏不作過多的講解。讀者能夠把進程理解爲操做系統管理應用程序的基本單位,每一個進程之間的資源是不能直接共享的。打開操做系統的任務管理器,咱們能夠看到當前操做系統都有那些進程,以下圖api
回顧以往的web開發,咱們的代碼,不管是HTML、CSS仍是Javascript,都是運行在瀏覽器的沙盒中的,咱們沒法越過瀏覽器的權限訪問系統自己的資源,代碼的能力被限制在了瀏覽器中。瀏覽器之因此這麼作,是爲了安全的考慮。設想一下,咱們在使用瀏覽器的時候,會打開各式各樣不一樣來源的網站,若是JavaScript代碼有能力訪問並操做本地操做系統的資源,那將是多麼可怕的事情。你在某天不當心打開了一個惡意的網站,可能你存儲在硬盤上的文件就被偷走了(都用不着去修電腦)。瀏覽器
但咱們要開發的是桌面應用程序,若是沒法訪問到本地的資源確定是不行的。Electron將nodejs巧妙的融合了進來,讓nodejs做爲整個程序的管家。管家擁有較高的權限,能夠訪問和操做本地資源,使用本來在瀏覽器中不提供的高級API。同時管家也管理着渲染進程窗口的建立和銷燬。因此,咱們將這個管家稱之爲主進程
。在使用Electron開發的程序中,會使用main.js做爲程序的主入口,該文件內代碼執行的內容,就是主進程中執行的內容。安全
下面咱們一塊兒來看看主進程中通常都作些什麼。架構
//main.js
var electron = require('electron');
var app = require('electron').app;
//初始化
app.on('ready', function(){
try{
//app ready
}catch(err){
log.error(err);
}
});
複製代碼
上面是一個最簡單的main.js例子。在例子中,咱們首先引入了electron
和electron.app
模塊。electron.app
對象控制着整個程序的生命週期,在這咱們只註冊了生命週期中的ready
事件,當ready事件被觸發的時候,表示整個程序已經初始化完畢,能夠開始進行建立窗口等業務邏輯了。app
在現實的應用中,主進程的代碼遠比上面的例子複雜的多。有許多需求特性的實現都是在主進程中完成,下面舉個例子進行講解。
在某些場景中,應用程序被要求在系統中只能同時開啓一個。因此當某個應該已經在系統中運行時,若是再次雙擊應用icon,程序應該將本身退掉,或者是把以前打開的程序退掉。
(function(){
app.makeSingleInstance(singleInstanceCallBack);
function singleInstanceCallBack(commandLine, workingDirectory){
console.log('command line: ', commandLine);
console.log('working directory: ', workingDirectory);
app.exit(0);
}
})();
複製代碼
這裏使用的是app.makeSingleInstance
api實現的這個功能。singleInstanceCallBack
函數是當第二個實例啓動時,第一個實例執行的回調,因此singleInstanceCallBack
裏面使用的app
實際上指向的是先打開的實例(剛接觸這個api的時候確實有點繞),上面的代碼中,singleInstanceCallBack
執行時,調用了app.exit
方法退出了先打開的程序。那咱們如何去判斷當前是第二個實例呢?其實,makeSingleInstance
的返回值是一個boolean類型的值,爲true時表示當前是第二個實例。若是需求是想讓第二個實例退出,則在當前的做用域中直接調用app.exit
便可。
Electron集成了Chromium來展現窗口界面,窗口中所看到的內容使用的都是HTML渲染出來的。 Chromium自己是多進程渲染頁面的架構(在默認狀況下,Chromium的默認策略是對每個tab新開一個進程,以確保每一個頁面是獨立且互不影響的。避免一個頁面的崩潰致使所有頁面沒法使用),因此Electron在展現窗口時,也會使用到Chromium的多進程架構。而這種多進程渲染架構在Electron中,就被稱之爲渲染進程(render process)。
在Electron中,每建立一個新的窗口,都是一個獨立的進程。
//main.js
const {BrowserWindow} = require('electron');
const window1 = new BrowserWindow({width: 200, height: 200})
const window2 = new BrowserWindow({width: 200, height: 200})
window1.loadURL('https://baidu.com');
window2.loadURL(`file://${__dirname}/index.html`)
複製代碼
在上面的代碼中,咱們建立了2個窗口,window1
和window2
。這兩個窗口就是互相獨立的進程。window1
窗口內容指向的是百度首頁,window2
窗口內容指向的是咱們本身開發的html頁面。在index.html中,咱們能夠像開發正常的web網頁同樣,開發窗口內容。如下是index.html的一個示例
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1,user-scalable=0">
<title>main page</title>
</head>
<body>
<div id="app">Hello World</div>
<script type="text/javascript" src="mainPage.js"></script>
</body>
</html>
複製代碼
在介紹主進程的篇幅中,咱們說到只有主進程纔有獲取本地資源的權限。實際場景中,有時須要將主進程中獲取的本地數據在窗口中展現出來,該怎麼實現呢?
在下一章,咱們會重點講解主進程與渲染進程之間如何通訊的知識。