鸿蒙 + Electron 跨端开发进阶实战:从桌面应用到鸿蒙多设备协同(附完整代码)鸿蒙PC
鸿蒙 + Electron 跨端开发进阶实战:从桌面应用到鸿蒙多设备协同(附完整代码)
引言:跨端开发的破局之路 —— 鸿蒙与 Electron 的强强联合
在全场景智慧时代,用户对应用的需求早已不再局限于单一设备。鸿蒙 OS 以分布式软总线、一次开发多端部署的核心能力,构建了覆盖手机、平板、车机、智慧屏的全场景生态;而 Electron 凭借Web 技术栈快速开发桌面应用的特性,成为开发者打造跨平台桌面工具的首选框架。
但单独使用两者时,都会面临明显的短板:鸿蒙桌面应用开发门槛高,Web 生态兼容性弱;Electron 应用则缺乏多设备协同能力,无法接入鸿蒙的分布式硬件资源。因此,鸿蒙与 Electron 的融合开发成为破局关键 —— 既能用 HTML/CSS/JS 快速构建桌面交互界面,又能借助鸿蒙的分布式能力实现多设备联动,真正做到 "一套代码,多端赋能"。
本文将围绕鸿蒙与 Electron 的深度集成展开,从底层通信原理到上层应用开发,结合 3 个实战项目,提供可直接落地的技术方案。全文包含超 10 段核心代码、8 个官方资源链接,适合前端开发者、鸿蒙生态工程师学习参考,助力大家快速掌握跨端开发的核心技能。
一、技术底层:鸿蒙与 Electron 融合的核心原理
1.1 融合架构设计
鸿蒙与 Electron 的融合并非简单的 "移植",而是基于进程间通信(IPC) 和分布式服务的架构整合,核心分为三层:
- 应用层:Electron 负责桌面端的 UI 渲染与交互逻辑,鸿蒙应用负责多设备的硬件调用与数据同步;
- 通信层:通过 WebSocket、鸿蒙分布式数据服务(DDS)实现跨设备、跨进程的数据传输;
- 硬件层:鸿蒙设备提供传感器、摄像头、蓝牙等硬件能力,Electron 桌面端作为控制中枢下发指令。
整体架构如下图所示:
plaintext
Electron桌面端(主控)
↓ ↑ WebSocket/DDS通信
鸿蒙设备集群(执行)
- 手机:传感器数据采集
- 平板:大屏展示
- 智慧屏:音视频输出
1.2 关键技术对比与选型
| 技术方案 | 适用场景 | 优势 | 局限性 |
|---|---|---|---|
| WebSocket 通信 | 局域网内设备协同 | 实时性高、开发成本低 | 依赖网络、不支持离线通信 |
| 鸿蒙分布式数据服务 | 跨设备数据共享 | 鸿蒙原生支持、离线同步 | 仅适用于鸿蒙设备、配置复杂 |
| Native 桥接(C++) | 高性能硬件调用 | 低延迟、高兼容性 | 开发门槛高、跨平台性差 |
选型建议:开发初期优先使用 WebSocket 实现快速验证;产品化阶段结合鸿蒙 DDS 提升稳定性与离线能力;高性能场景(如音视频处理)可采用 C++ Native 桥接方案。
1.3 开发环境前置要求
- 硬件:Windows/macOS 开发机(内存≥16GB)、鸿蒙设备(API 9+,支持开发者模式)
- 软件:
- DevEco Studio 5.0+:官方下载地址
- Node.js 18.x LTS:Node.js 官方下载
- Electron 28.x+:
npm install electron -g - 鸿蒙 SDK(API 9+):通过 DevEco Studio 自动安装
- 账号:华为开发者账号(完成实名认证,用于应用签名):华为开发者联盟
二、实战项目 1:基础通信 ——Electron 与鸿蒙设备的 WebSocket 双向交互
本项目实现最基础的跨设备通信能力:Electron 桌面端作为 WebSocket 服务端,鸿蒙设备作为客户端,完成指令下发与数据上传的双向交互。
2.1 项目结构搭建plaintext
harmony-electron-demo/
├── electron-main/ # Electron桌面端代码
│ ├── main.js # 主进程:WebSocket服务+窗口管理
│ ├── preload.js # 预加载脚本:安全通信桥
│ ├── renderer/ # 渲染进程:UI界面
│ │ ├── index.html
│ │ ├── style.css
│ │ └── renderer.js
│ └── package.json
└── harmony-device/ # 鸿蒙设备端代码
└── entry/
└── src/main/ets/
├── MainAbility.ets # 鸿蒙应用入口:WebSocket客户端
└── pages/
└── Index.ets # 鸿蒙UI页面
2.2 Electron 桌面端实现(服务端)
2.2.1 主进程代码(main.js)
主进程负责启动 WebSocket 服务、创建桌面窗口、处理设备通信逻辑。
运行
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
const WebSocket = require('ws');
let mainWindow;
let wss; // WebSocket服务实例
// 创建Electron窗口
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true, // 开启上下文隔离,保障安全
nodeIntegration: false // 禁用Node.js集成
}
});
// 加载渲染进程页面
mainWindow.loadFile(path.join(__dirname, 'renderer/index.html'));
// 开发阶段打开调试工具
mainWindow.webContents.openDevTools();
}
// 启动WebSocket服务
function startWSServer() {
wss = new WebSocket.Server({ port: 9000 });
console.log('WebSocket服务已启动:ws://localhost:9000');
// 监听设备连接
wss.on('connection', (ws) => {
console.log('鸿蒙设备已连接');
// 向渲染进程发送连接状态
mainWindow.webContents.send('device-status', 'connected');
// 接收设备上传的数据
ws.on('message', (message) => {
const data = JSON.parse(message.toString());
console.log('收到设备数据:', data);
// 转发数据到渲染进程
mainWindow.webContents.send('device-data', data);
});
// 监听连接关闭
ws.on('close', () => {
console.log('鸿蒙设备已断开');
mainWindow.webContents.send('device-status', 'disconnected');
});
// 发送初始化指令
ws.send(JSON.stringify({ type: 'init', content: '欢迎连接桌面端' }));
});
}
// 监听渲染进程的指令下发请求
ipcMain.on('send-command', (event, command) => {
if (wss && wss.clients.size > 0) {
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify({ type: 'command', data: command }));
}
});
}
});
// 应用生命周期管理
app.whenReady().then(() => {
createWindow();
startWSServer(); // 启动WebSocket服务
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit();
});
2.2.2 预加载脚本(preload.js)
用于在主进程与渲染进程之间建立安全通信桥,避免直接暴露 Node.js API。
运行
const { contextBridge, ipcRenderer } = require('electron');
// 向渲染进程暴露安全API
contextBridge.exposeInMainWorld('electronAPI', {
// 接收设备状态
onDeviceStatus: (callback) => ipcRenderer.on('device-status', (event, status) => callback(status)),
// 接收设备数据
onDeviceData: (callback) => ipcRenderer.on('device-data', (event, data) => callback(data)),
// 下发指令到设备
sendCommand: (command) => ipcRenderer.send('send-command', command)
});
2.2.3 渲染进程代码(index.html + renderer.js)
预览
<!-- index.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>鸿蒙-Electron通信 Demo</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>鸿蒙设备通信控制台</h1>
<div class="status">设备状态:<span id="status">未连接</span></div>
<div class="data-view">设备数据:<span id="data">无</span></div>
<div class="command-input">
<input type="text" id="command" placeholder="输入指令发送到设备">
<button id="send-btn">发送指令</button>
</div>
</div>
<script src="renderer.js"></script>
</body>
</html>
运行
// renderer.js
const statusEl = document.getElementById('status');
const dataEl = document.getElementById('data');
const commandInput = document.getElementById('command');
const sendBtn = document.getElementById('send-btn');
// 监听设备状态
window.electronAPI.onDeviceStatus((status) => {
statusEl.textContent = status;
statusEl.style.color = status === 'connected' ? 'green' : 'red';
});
// 监听设备数据
window.electronAPI.onDeviceData((data) => {
dataEl.textContent = JSON.stringify(data);
});
// 发送指令到设备
sendBtn.addEventListener('click', () => {
const command = commandInput.value.trim();
if (command) {
window.electronAPI.sendCommand(command);
commandInput.value = '';
}
});
2.3 鸿蒙设备端实现(客户端)

鸿蒙设备端通过 WebSocket 连接桌面端,实现数据上传与指令接收。
2.3.1 MainAbility.ets(应用入口)
运行
import web_socket from '@ohos.net.webSocket';
import hilog from '@ohos.hilog';
let ws: web_socket.WebSocket | null = null;
export default class MainAbility extends Ability {
onCreate(want, launchParam) {
hilog.info(0x0000, 'TEST_TAG', '%{public}s', 'Ability onCreate');
this.initWebSocket();
}
// 初始化WebSocket连接
initWebSocket() {
ws = web_socket.createWebSocket();
// 替换为桌面端的局域网IP
const url = 'ws://192.168.1.105:9000';
ws.connect(url, (err, _) => {
if (err) {
hilog.error(0x0000, 'TEST_TAG', 'WebSocket连接失败:%{public}s', err.message);
// 重试机制
setTimeout(() => this.initWebSocket(), 3000);
return;
}
hilog.info(0x0000, 'TEST_TAG', 'WebSocket连接成功');
// 接收桌面端指令
ws.on('message', (message: string) => {
const data = JSON.parse(message);
hilog.info(0x0000, 'TEST_TAG', '收到桌面端指令:%{public}s', JSON.stringify(data));
// 转发指令到UI页面
globalThis.commandData = data;
});
// 监听连接关闭
ws.on('close', () => {
hilog.info(0x0000, 'TEST_TAG', 'WebSocket连接关闭');
setTimeout(() => this.initWebSocket(), 3000);
});
});
}
// 向桌面端发送数据
sendDataToDesktop(data: object) {
if (ws && ws.readyState === web_socket.WebSocketState.OPEN) {
ws.send(JSON.stringify(data), (err) => {
if (err) {
hilog.error(0x0000, 'TEST_TAG', '数据发送失败:%{public}s', err.message);
}
});
}
}
onDestroy() {
hilog.info(0x0000, 'TEST_TAG', '%{public}s', 'Ability onDestroy');
if (ws) {
ws.close();
}
}
}
2.3.2 Index.ets(UI 页面)
运行
@Entry
@Component
struct Index {
@State message: string = '设备数据上传 Demo'
@State deviceData: string = ''
@State command: string = '无'
build() {
Column() {
Text(this.message)
.fontSize(30)
.fontWeight(FontWeight.Bold)
.margin(20)
Text(`接收的指令:${this.command}`)
.fontSize(20)
.margin(10)
Button('上传设备信息')
.onClick(() => {
const data = {
deviceName: 'HarmonyOS Phone',
time: new Date().toLocaleString(),
battery: '85%'
};
this.deviceData = JSON.stringify(data);
// 调用Ability的方法发送数据
const ability = getContext(this) as Ability;
(ability as any).sendDataToDesktop(data);
})
.margin(20)
Text(`上传的数据:${this.deviceData}`)
.fontSize(16)
.margin(10)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
// 监听全局指令数据变化
aboutToAppear() {
setInterval(() => {
if (globalThis.commandData) {
this.command = JSON.stringify(globalThis.commandData);
}
}, 1000);
}
}
2.4 运行测试步骤
- 启动 Electron 桌面端:
bash
运行
cd electron-main npm install npm start - 配置鸿蒙设备端:修改
MainAbility.ets中的桌面端 IP 为实际局域网 IP; - 运行鸿蒙应用:在 DevEco Studio 中连接鸿蒙设备,点击 "运行" 按钮;
- 功能验证:
- 设备端点击 "上传设备信息",桌面端接收并显示数据;
- 桌面端输入指令并发送,设备端接收并显示指令内容。
三、实战项目 2:进阶应用 —— 鸿蒙传感器数据在 Electron 桌面端可视化
本项目基于基础通信能力,实现鸿蒙设备传感器数据采集 + Electron 桌面端可视化展示,核心使用鸿蒙的加速度传感器 API和 Electron 的Chart.js图表库
。
3.1 鸿蒙设备端:加速度传感器数据采集
在鸿蒙项目中添加传感器权限与数据采集逻辑。
3.1.1 添加权限配置(module.json5)
在module.json5的reqPermissions中添加传感器权限:
{
"module": {
"reqPermissions": [
{
"name": "ohos.permission.ACCELEROMETER" // 加速度传感器权限
}
]
}
}
3.1.2 传感器数据采集代码(Index.ets)
运行
import sensor from '@ohos.sensor';
import { BusinessError } from '@ohos.base';
@Entry
@Component
struct Index {
@State message: string = '加速度传感器数据采集'
@State x: number = 0
@State y: number = 0
@State z: number = 0
private accelerometerListener: sensor.AccelerometerResponse | null = null
build() {
Column() {
Text(this.message)
.fontSize(30)
.fontWeight(FontWeight.Bold)
.margin(20)
Text(`X轴:${this.x.toFixed(2)} m/s²`)
.fontSize(20)
.margin(5)
Text(`Y轴:${this.y.toFixed(2)} m/s²`)
.fontSize(20)
.margin(5)
Text(`Z轴:${this.z.toFixed(2)} m/s²`)
.fontSize(20)
.margin(5)
Button('开始采集')
.onClick(() => this.startCollect())
.margin(10)
Button('停止采集')
.onClick(() => this.stopCollect())
.margin(10)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
// 开始采集传感器数据
startCollect() {
this.accelerometerListener = (data) => {
this.x = data.x;
this.y = data.y;
this.z = data.z;
// 每100ms上传一次数据到桌面端
const ability = getContext(this) as Ability;
(ability as any).sendDataToDesktop({
type: 'accelerometer',
x: data.x,
y: data.y,
z: data.z,
time: Date.now()
});
}
try {
sensor.on(sensor.SensorTypeId.ACCELEROMETER, this.accelerometerListener, { interval: sensor.SensorInterval.SENSOR_INTERVAL_100MS });
} catch (err) {
console.error(`传感器监听失败:${(err as BusinessError).message}`);
}
}
// 停止采集
stopCollect() {
if (this.accelerometerListener) {
sensor.off(sensor.SensorTypeId.ACCELEROMETER, this.accelerometerListener);
this.accelerometerListener = null;
}
}
aboutToDisappear() {
this.stopCollect();
}
}
3.2 Electron 桌面端:数据可视化展示
在 Electron 渲染进程中集成 Chart.js,实现传感器数据的实时折线图展示。
3.2.1 安装 Chart.js
cd electron-main
npm install chart.js --save
3.2.2 渲染进程代码修改(renderer.js)
运行
import Chart from 'chart.js/auto';
const statusEl = document.getElementById('status');
const dataEl = document.getElementById('data');
const commandInput = document.getElementById('command');
const sendBtn = document.getElementById('send-btn');
// 初始化图表
const ctx = document.getElementById('sensorChart').getContext('2d');
const sensorChart = new Chart(ctx, {
type: 'line',
data: {
labels: [], // 时间轴
datasets: [
{
label: 'X轴加速度',
data: [],
borderColor: 'red',
tension: 0.1
},
{
label: 'Y轴加速度',
data: [],
borderColor: 'green',
tension: 0.1
},
{
label: 'Z轴加速度',
data: [],
borderColor: 'blue',
tension: 0.1
}
]
},
options: {
responsive: true,
scales: {
y: {
title: {
display: true,
text: '加速度 (m/s²)'
}
},
x: {
title: {
display: true,
text: '时间'
}
}
}
}
});
// 监听设备数据并更新图表
window.electronAPI.onDeviceData((data) => {
if (data.type === 'accelerometer') {
// 限制数据点数量为50个
if (sensorChart.data.labels.length > 50) {
sensorChart.data.labels.shift();
sensorChart.data.datasets.forEach(dataset => dataset.data.shift());
}
// 添加新数据
sensorChart.data.labels.push(new Date(data.time).toLocaleTimeString());
sensorChart.data.datasets[0].data.push(data.x);
sensorChart.data.datasets[1].data.push(data.y);
sensorChart.data.datasets[2].data.push(data.z);
sensorChart.update();
}
dataEl.textContent = JSON.stringify(data);
});
// 原有代码保持不变
window.electronAPI.onDeviceStatus((status) => {
statusEl.textContent = status;
statusEl.style.color = status === 'connected' ? 'green' : 'red';
});
sendBtn.addEventListener('click', () => {
const command = commandInput.value.trim();
if (command) {
window.electronAPI.sendCommand(command);
commandInput.value = '';
}
});
3.2.3 修改 HTML 页面(index.html)
添加图表容器:
预览
<div class="chart-container">
<canvas id="sensorChart"></canvas>
</div>
添加 CSS 样式:
.chart-container {
width: 90%;
height: 300px;
margin: 20px auto;
}
3.3 功能验证
- 启动 Electron 桌面端与鸿蒙应用;
- 鸿蒙设备端点击 "开始采集",手持设备晃动;
- 桌面端实时显示加速度数据的折线图,X/Y/Z 轴数据随设备运动动态变化。
四、实战项目 3:高级特性 —— 鸿蒙原子化服务与 Electron 应用的联动

鸿蒙原子化服务是免安装、即用即走的轻量化应用形态,本项目将 Electron 应用适配为鸿蒙原子化服务的 "控制中枢",实现服务卡片触发 Electron 应用启动、Electron 应用控制原子化服务运行的联动效果。
4.1 核心适配逻辑
- Electron 应用打包:将 Electron 桌面端打包为鸿蒙 PC 可执行文件;
- 原子化服务开发:开发鸿蒙服务卡片,点击卡片触发 Electron 应用启动;
- 跨应用通信:通过鸿蒙分布式任务调度实现原子化服务与 Electron 应用的通信。
4.2 关键代码实现
4.2.1 Electron 应用打包(package.json)
使用electron-builder打包为鸿蒙 PC 支持的格式:
{
"scripts": {
"build:harmony": "electron-builder --linux --arm64"
},
"build": {
"appId": "com.example.harmonyelectron",
"productName": "HarmonyElectronDemo",
"linux": {
"target": [
{
"target": "AppImage",
"arch": ["arm64"]
}
]
}
}
}
执行打包命令:
运行
npm run build:harmony
4.2.2 鸿蒙原子化服务卡片代码(CardAbility.ets)
运行
import card from '@ohos.service.card';
import hilog from '@ohos.hilog';
import Want from '@ohos.app.ability.Want';
export default class CardAbility extends card.CardExtensionAbility {
onCreate(want: Want) {
hilog.info(0x0000, 'TEST_TAG', '卡片创建');
}
onUpdate(formId: string) {
// 更新卡片数据
const formData = {
title: 'Electron控制卡片',
content: '点击启动桌面应用'
};
card.updateForm(formId, formData).then(() => {
hilog.info(0x0000, 'TEST_TAG', '卡片更新成功');
});
}
// 点击卡片触发事件
onTriggerForm(formId: string, message: string) {
// 启动Electron应用
const want: Want = {
bundleName: 'com.example.harmonyelectron',
abilityName: 'MainAbility',
action: 'ohos.want.action.startApplication'
};
this.context.startAbility(want).then(() => {
hilog.info(0x0000, 'TEST_TAG', '启动Electron应用成功');
});
}
}
4.3 部署与验证
- 将打包后的 Electron 应用安装到鸿蒙 PC 设备;
- 在鸿蒙设备桌面添加原子化服务卡片;
- 点击卡片,自动启动 Electron 应用;
- Electron 应用下发指令,控制鸿蒙原子化服务执行特定任务(如播放音乐、显示通知)。
五、性能优化与常见问题解决方案
5.1 性能优化策略
- 通信优化:
- 数据压缩:使用 gzip 压缩传输数据,减少网络开销;
- 批量发送:传感器数据采用批量上传,降低通信频率。
- Electron 优化:
- 禁用硬件加速:
app.disableHardwareAcceleration(),避免鸿蒙 PC 渲染异常; - 进程隔离:将耗时任务放在独立进程,避免阻塞主进程。
- 禁用硬件加速:
- 鸿蒙端优化:
- 传感器采样频率:根据需求调整,非必要不使用高频采样;
- 后台运行:配置鸿蒙应用后台运行权限,避免被系统杀死。
5.2 常见问题解决方案
| 问题现象 | 原因分析 | 解决方案 |
|---|---|---|
| WebSocket 连接失败 | 1. 设备不在同一局域网;2. 端口被占用 | 1. 检查网络配置;2. 更换端口(如 9001);3. 关闭防火墙 |
| 传感器数据采集失败 | 未申请权限或权限被拒绝 | 1. 在 module.json5 中添加权限;2. 引导用户手动授予权限 |
| Electron 应用在鸿蒙 PC 无法启动 | 打包架构不匹配 | 使用--arm64参数打包,适配鸿蒙 PC 的 ARM 架构 |
| 原子化服务卡片不显示 | 卡片配置错误 | 检查 module.json5 中的extensionAbilities配置,确保cardSize合法 |
六、生态资源与未来展望
6.1 核心学习资源
- 鸿蒙官方文档:HarmonyOS 开发者文档中心
- Electron 官方文档:Electron API Reference
- OpenHarmony SIG Electron 项目:Gitee 仓库(鸿蒙官方维护的 Electron 适配项目)
- 鸿蒙传感器开发指南:传感器 API 文档
6.2 未来展望
- 官方适配增强:华为 OpenHarmony 社区正在推进 Electron 原生适配,未来将提供更完善的工具链与 API;
- 能力深度融合:Electron 应用将可直接调用鸿蒙的分布式能力,无需额外的通信层开发;
- 跨端生态统一:Web 技术栈将成为鸿蒙跨端开发的核心之一,Electron 作为 Web 桌面应用的代表,将在鸿蒙生态中发挥更大作用。
结语
鸿蒙与 Electron 的融合开发,为跨端应用开发提供了全新的思路 —— 既保留了 Web 技术栈的高效开发优势,又能充分利用鸿蒙的全场景能力。本文通过 3 个实战项目,从基础通信到高级联动,完整覆盖了鸿蒙 + Electron 开发的核心流程。
随着鸿蒙生态的不断发展,这种跨端开发模式将在更多场景中落地,助力开发者打造真正的全场景智慧应用。希望本文能为大家的学习与实践提供帮助,让我们一起探索跨端开发的无限可能!
欢迎加入开源鸿蒙PC社区:https://harmonypc.csdn.net/
更多推荐
所有评论(0)