Electron架构简析

概述

简单来说,Electron为用纯JavaScript创建桌面应用提供了运行时。原理是,Electron调用你在package.json中定义的main文件并执行它。main文件(通常被命名为main.js)会创建一个内含渲染完的web页面的应用窗口,并添加与你操作系统的原生GUI(图形界面)交互的功能。
详细地说,当用Electron启动一个应用,会创建一个主进程。这个主进程负责与你系统原生的GUI进行交互并为你的应用创建GUI(在你的应用窗口)。



electron_process

如上图,electron由主进程main process启动,通过BrowserWindow实例创建渲染进程renderer process,每个渲染进程都是相互独立渲染。考虑到安全问题,在渲染进程里面不允许直接调用GUI API,如果想要调用,必须通过和主进程通讯,请求主进程完成相应的调用。在 Electron,我们提供几种方法用于主进程和渲染进程之间的通讯。像ipcRendereripcMain模块用于发送消息,remote模块用于 RPC 方式通讯。这些内容都可以在一个 FAQ 中查看how to share data between web pages

打造你第一个 Electron 应用

主进程 main.js:

'use strict';
const electron = require('electron');
// Module to control application life.
const app = electron.app;
app.title = "AppTitle";
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow;

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;

function createWindow () {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    "title": "AppTitle",
    "toolbar": true,
    "width": 1000,
    "height": 600,
    "min_width": 1000,
    "min_height": 600,
    "resizable": true,
    // "frame": false,
    "autoHideMenuBar" : false,
    "icon":__dirname+"/app/icons/application.ico"
  });

  // and load the index.html of the app.
  mainWindow.loadURL('file://' + __dirname + '/app/index.html');

  // Open the DevTools.
  mainWindow.webContents.openDevTools();

  // Emitted when the window is closed.
  mainWindow.on('closed', function() {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', createWindow);

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', function () {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow();
  }
});

代码里面的

mainWindow.loadURL('file://' + __dirname + '/app/index.html');

加载本地app的URL地址,就可以运行App

主进程与渲染进程的通讯

上面已经说过像ipcRendereripcMain模块用于发送消息,remote模块用于 RPC 方式通讯

ipcMain

// In main process.
const {ipcMain} = require('electron');
ipcMain.on('asynchronous-message', (event, arg) => {
console.log(arg);  // prints "ping"
event.sender.send('asynchronous-reply', 'pong');
});

ipcMain.on('synchronous-message', (event, arg) => {
console.log(arg);  // prints "ping"
event.returnValue = 'pong';
});

ipcRenderer

// In renderer process (web page).
const {ipcRenderer} = require('electron');
console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); // prints "pong"

ipcRenderer.on('asynchronous-reply', (event, arg) => {
console.log(arg); // prints "pong"
});
ipcRenderer.send('asynchronous-message', 'ping');

remote

main process

// main process mapNumbers.js
exports.withRendererCallback = (mapper) => {
return [1,2,3].map(mapper);
};

exports.withLocalCallback = () => {
return exports.mapNumbers(x => x + 1);
};

renderer process

// renderer process
const mapNumbers = require('remote').require('./mapNumbers');

const withRendererCb = mapNumbers.withRendererCallback(x => x + 1);

const withLocalCb = mapNumbers.withLocalCallback();

console.log(withRendererCb, withLocalCb); // [true, true, true], [2, 3, 4]

参考:
https://github.com/electron/electron/tree/master/docs-translations/zh-CN
http://www.voidcn.com/blog/DJY1992/article/p-5793178.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,898评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,401评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,058评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,539评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,382评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,319评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,706评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,370评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,664评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,715评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,476评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,326评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,730评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,003评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,275评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,683评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,877评论 2 335

推荐阅读更多精彩内容