基于Web技术栈构建鸿蒙桌面应用,一套代码多端运行。

一、前言

Electron作为一款成熟的跨平台桌面应用开发框架,已成功适配鸿蒙操作系统,使开发者能够使用熟悉的Web技术栈(HTML、CSS、JavaScript)来构建可在HarmonyOS上运行的桌面应用。

本文将深入探讨Electron在鸿蒙系统上的实现原理、环境配置与关键代码解析。

二、Electron鸿蒙化架构原理

2.1 基本架构

Electron在鸿蒙系统中的架构基于传统的Chromium渲染引擎Node.js运行时组合,并通过鸿蒙原生能力进行增强:

  • 主进程:负责应用生命周期管理、窗口创建和系统原生API调用
  • 渲染进程:运行用户界面,基于Chromium内核,安全隔离
  • 原生适配层:通过.so库文件实现Electron与鸿蒙系统的桥梁

2.2 鸿蒙适配关键组件

在鸿蒙平台上,Electron依赖几个核心原生库:
在这里插入图片描述

  • libelectron.so:Electron主库,提供核心API
  • libadapter.so:鸿蒙特性适配层,实现Electron API到鸿蒙API的映射
  • libffmpeg.so:媒体处理支持
  • libc++_shared.so:C++运行时库

三、项目结构与核心代码解析

3.1 项目目录结构

标准的Electron鸿蒙项目应遵循以下结构:

app/
├── main.js           # 主进程入口文件(必需)
├── package.json      # 项目配置文件(必需)
├── index.html        # 渲染进程页面
├── renderer.js       # 渲染进程逻辑
└── node_modules/     # 依赖包(如果有)

应用代码需放置在特定目录:web_engine/src/main/resources/resfile/resources/app/

3.2 主进程代码(main.js)

主进程负责创建应用窗口和管理应用生命周期:

const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');

function createWindow() {
  // 创建浏览器窗口
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
      preload: path.join(__dirname, 'preload.js')  // 预加载脚本
    }
  });

  // 加载应用的index.html
  win.loadFile('index.html');
  
  // 开发环境下自动打开开发者工具
  if (process.env.NODE_ENV === 'development') {
    win.webContents.openDevTools();
  }
}

// 应用准备就绪时创建窗口
app.whenReady().then(createWindow);

// 当所有窗口关闭时退出应用(macOS除外)
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

// IPC通信处理示例
ipcMain.handle('select-files', async (event, options) => {
  // 处理文件选择逻辑
  const result = await dialog.showOpenDialog(options);
  return result;
});

3.3 预加载脚本(preload.js)

预加载脚本在渲染进程加载前执行,用于安全地暴露API:

const { contextBridge, ipcRenderer } = require('electron');

// 通过contextBridge向渲染进程暴露受保护的方法
contextBridge.exposeInMainWorld('electronAPI', {
  // 平台信息
  platform: {
    processPlatform: process.platform,
    osType: require('os').type(),
  },
  
  // 文件选择API
  selectFiles: (options) => ipcRenderer.invoke('select-files', options),
  
  // 其他自定义API
  queryDaxue: (daxue) => ipcRenderer.invoke('query-daxue', daxue)
});

3.4 渲染进程代码(renderer.js)

渲染进程处理用户界面和交互逻辑:

// 使用预加载脚本暴露的API
document.getElementById('select-file').addEventListener('click', async () => {
  try {
    // 检查Electron API是否可用
    if (!window.electronAPI || !window.electronAPI.selectFiles) {
      // 回退方案:使用浏览器原生文件选择
      document.getElementById('file-input').click();
      return;
    }
    
    // 使用Electron API选择文件
    const result = await window.electronAPI.selectFiles({
      properties: ['openFile', 'multiSelections']
    });
    
    if (!result.canceled) {
      // 处理选中的文件
      displayFiles(result.filePaths);
    }
  } catch (error) {
    console.error('选择文件失败:', error);
  }
});

// 调用自定义API示例
async function queryUniversity() {
  if (window.electronAPI) {
    const data = await window.electronAPI.queryDaxue('武汉大学');
    updateUI(data);
  }
}

3.5 前端页面(index.html)

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Electron鸿蒙应用</title>
  <style>
    body {
      font-family: 'HarmonyOS Sans', sans-serif;
      margin: 0;
      padding: 20px;
    }
  </style>
</head>
<body>
  <h1>欢迎使用Electron on HarmonyOS!</h1>
  <p>这是运行在鸿蒙系统上的Electron应用</p>
  
  <button id="select-file">选择文件</button>
  <input type="file" id="file-input" style="display: none;" multiple>
  
  <div id="file-list"></div>
  
  <script src="renderer.js"></script>
</body>
</html>

3.6 包配置文件(package.json)

{
  "name": "electron-harmonyos-app",
  "version": "1.0.0",
  "description": "基于Electron的鸿蒙跨平台应用",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "build:harmony": "node build-harmony.js"
  },
  "dependencies": {
    "electron": "^34.0.0"
  },
  "harmony": {
    "bundleName": "com.example.electronapp",
    "vendor": "example",
    "versionCode": 1,
    "versionName": "1.0.0"
  }
}

四、鸿蒙特性适配与进阶功能

4.1 平台检测与兼容性处理

在鸿蒙平台上,需要特别处理平台检测逻辑:

// 平台检测与兼容性处理
function getPlatformInfo() {
  // 在鸿蒙系统中,process.platform 返回 'ohos'
  const platform = process.platform;
  
  // 兼容性处理:对于不识别'ohos'的三方库
  if (platform === 'ohos') {
    // 可根据需要映射为其他平台标识
    return {
      actual: 'ohos',
      compatible: 'linux'  // 或根据库的要求返回其他值
    };
  }
  
  return { actual: platform, compatible: platform };
}

// 在应用启动时设置平台兼容性
if (process.platform === 'ohos') {
  // 针对鸿蒙平台的特定配置
  app.disableHardwareAcceleration(); // 解决某些渲染问题
}

4.2 应用配置与元数据

鸿蒙应用需要特定的配置文件module.json5

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "versionCode": 1,
    "versionName": "1.0.0",
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "tablet",
      "2in1"  // 支持平板和2合1设备
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages"
  }
}

4.3 应用名称与图标定制

  • 应用名称:修改ohos_hap/electron/src/main/resources/zh_CN/element/string.json
  • 应用图标:替换ohos_hap/AppScope/resources/base/media目录下的图标文件

五、调试与打包部署

5.1 应用调试

  • 日志查看:在DevEco Studio的Log面板中过滤Electron关键词
  • 开发者工具:在main.js中添加win.webContents.openDevTools()自动打开Chrome DevTools

5.2 常见问题解决

  1. "SysCap不匹配"错误:检查module.json5中的reqSysCapabilities,移除测试类能力

  2. "找不到.so文件"错误:确认libs/arm64-v8a目录包含必要的核心库

  3. Electron窗口不显示:尝试在main.js中添加app.disableHardwareAcceleration()禁用硬件加速

六、原理深入解析

6.1 进程间通信(IPC)机制

Electron在鸿蒙上的IPC通信保持了与标准Electron相同的架构:

  • 主进程:使用ipcMain处理来自渲染进程的请求
  • 渲染进程:通过ipcRenderer发送请求(经由预加载脚本代理)
  • 安全隔离:通过contextIsolation和预加载脚本确保安全性

6.2 鸿蒙原生能力集成

通过适配层,Electron应用可以间接调用鸿蒙原生能力:

  • 文件系统访问:通过鸿蒙的文件选择器实现
  • 窗口管理:利用鸿蒙的窗口管理器创建和管理窗口
  • 生命周期管理:与鸿蒙应用生命周期对接

七、总结

Electron for HarmonyOS为Web开发者提供了快速进入鸿蒙生态的捷径,通过熟悉的Web技术栈即可开发鸿蒙桌面应用。其核心实现原理是基于适配层将Electron API映射到鸿蒙原生API,同时保持了与标准Electron极高的兼容性。

尽管目前仍在完善阶段,但这一方案已显示出巨大潜力,能够显著降低鸿蒙应用开发门槛,促进鸿蒙生态繁荣。随着鸿蒙PC生态的持续发展,Electron在跨平台开发中的重要性将进一步提升。

学习资源

Logo

赋能鸿蒙PC开发者,共建全场景原生生态,共享一次开发多端部署创新价值。

更多推荐