前言
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
从这篇开始,我们正式进入OpenHarmony适配实战阶段。前面六篇铺垫了足够的理论基础,现在该动手了。
第一步是创建OpenHarmony的插件工程目录。这个过程说起来简单------不就是建几个文件夹、写几个配置文件嘛------但实际操作中有不少细节容易搞错。我第一次创建ohos目录的时候,oh-package.json5里的main字段写错了,导致插件怎么都加载不上,排查了大半天。
今天我会把ohos目录下的每一个文件都讲清楚,包括它的作用、配置项含义、以及我踩过的坑。跟着做一遍,保证你能顺利创建出一个可用的OpenHarmony插件工程。
💡 前置条件:确保你已经按照第2篇的步骤搭建好了开发环境,DevEco Studio和Flutter-OHOS SDK都能正常工作。
一、ohos 目录结构规范与文件说明
1.1 完整目录结构
flutter_speech插件的ohos目录结构如下:

1.2 各文件职责说明
| 文件 | 职责 | 是否手动编辑 | 重要程度 |
|---|---|---|---|
| FlutterSpeechPlugin.ets | 插件核心实现代码 | ✅ 是 | ⭐⭐⭐⭐⭐ |
| module.json5 | 模块类型和设备声明 | ✅ 是 | ⭐⭐⭐⭐ |
| oh-package.json5 | 包名、版本、依赖 | ✅ 是 | ⭐⭐⭐⭐⭐ |
| build-profile.json5 | 构建模式配置 | ⚠️ 偶尔 | ⭐⭐⭐ |
| index.ets | 插件导出入口 | ✅ 是 | ⭐⭐⭐⭐ |
| hvigorfile.ts | 构建脚本 | ❌ 一般不改 | ⭐⭐ |
| BuildProfile.ets | 构建配置类 | ❌ 自动生成 | ⭐ |
| oh-package-lock.json5 | 依赖版本锁定 | ❌ 自动生成 | ⭐ |
| local.properties | 本地SDK路径 | ❌ 不提交git | ⭐ |
📌 目录命名规范 :
src/main/ets/components/plugin/这个路径是Flutter-OHOS插件的约定俗成。虽然理论上你可以放在其他位置,但建议遵循这个规范,方便其他开发者理解你的代码。
1.3 与Android目录结构的对比
Android目录 OpenHarmony目录
───────── ──────────────
android/ ohos/
├── src/main/ ├── src/main/
│ ├── java/com/.../ │ ├── ets/components/plugin/
│ │ └── Plugin.java │ │ └── Plugin.ets
│ └── AndroidManifest.xml │ └── module.json5
├── build.gradle ├── build-profile.json5
└── (settings.gradle) ├── oh-package.json5
└── index.ets
| 对比项 | Android | OpenHarmony |
|---|---|---|
| 代码语言 | Java (.java) | ArkTS (.ets) |
| 模块配置 | AndroidManifest.xml | module.json5 |
| 构建配置 | build.gradle | build-profile.json5 |
| 包管理 | build.gradle (dependencies) | oh-package.json5 |
| 入口文件 | 无(自动扫描) | index.ets |
二、oh-package.json5 依赖配置
2.1 文件内容解析
这是flutter_speech的oh-package.json5:
json5
{
"name": "flutter_speech",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "index.ets",
"author": "",
"license": "Apache-2.0",
"dependencies": {}
}
逐字段解析:
| 字段 | 值 | 说明 | 注意事项 |
|---|---|---|---|
| name | "flutter_speech" | 包名 | 必须和pubspec.yaml的name一致 |
| version | "1.0.0" | 版本号 | 建议和pubspec.yaml保持同步 |
| description | "Please describe..." | 描述 | 建议改成有意义的描述 |
| main | "index.ets" | 入口文件 | 极其重要,写错插件就加载不了 |
| author | "" | 作者 | 可选 |
| license | "Apache-2.0" | 许可证 | 和项目整体保持一致 |
| dependencies | {} | 依赖 | 当前无额外依赖 |
🤦 我的踩坑经历 :第一次创建这个文件时,我把
main写成了"src/main/ets/components/plugin/FlutterSpeechPlugin.ets",结果插件死活加载不上。后来才发现main应该指向index.ets,由index.ets再导出插件类。这个坑浪费了我大半天时间。
2.2 依赖管理
如果你的插件需要依赖其他OpenHarmony库,在dependencies中声明:
json5
{
"dependencies": {
"@ohos/flutter_ohos": "file:./libs/flutter_ohos.har"
// 如果需要其他依赖,在这里添加
}
}
flutter_speech的情况比较特殊------它不需要在oh-package.json5中声明@ohos/flutter_ohos依赖,因为这个依赖是由Flutter-OHOS构建系统自动注入的。
2.3 与package.json的区别
如果你有Node.js开发经验,会觉得oh-package.json5很眼熟。它确实借鉴了npm的设计,但有几个区别:
| 对比项 | npm (package.json) | ohpm (oh-package.json5) |
|---|---|---|
| 格式 | 严格JSON | JSON5(支持注释) |
| 包管理器 | npm/yarn | ohpm |
| 仓库 | npmjs.com | ohpm.openharmony.cn |
| 入口字段 | "main" | "main" |
| 脚本 | "scripts" | 不支持 |
三、build-profile.json5 构建配置
3.1 文件内容

3.2 字段说明
| 字段 | 值 | 说明 |
|---|---|---|
| apiType | "stageMode" | API模型类型,Stage模型是OpenHarmony的新模型 |
| buildOption | {} | 构建选项,可以配置编译参数 |
| targets | [{"name": "default"}] | 构建目标,default是默认目标 |
这个文件通常不需要修改。但如果你需要配置特殊的编译选项(比如混淆、优化级别),可以在buildOption中添加:
json5
{
"apiType": "stageMode",
"buildOption": {
"arkOptions": {
"runtimeOnly": {
"sources": []
}
}
},
"targets": [
{
"name": "default"
}
]
}
3.3 Stage模型 vs FA模型
OpenHarmony有两种应用模型:
| 模型 | 状态 | 适用场景 | flutter_speech用的 |
|---|---|---|---|
| FA模型 | 已废弃 | 旧版应用 | ❌ |
| Stage模型 | 推荐 | 新版应用 | ✅ |
📌 一定要用Stage模型。FA模型已经不再维护,新的API(包括Core Speech Kit)只在Stage模型下可用。
四、module.json5 模块声明
4.1 文件内容

4.2 字段详解
| 字段 | 值 | 说明 | 重要性 |
|---|---|---|---|
| name | "flutter_speech" | 模块名称 | 必须和oh-package.json5的name一致 |
| type | "har" | 模块类型 | 必须是har(HarmonyOS Archive) |
| deviceTypes | ["default", "tablet"] | 支持的设备类型 | 根据需要配置 |
4.3 模块类型说明
OpenHarmony有几种模块类型:
| 类型 | 全称 | 用途 | 插件用哪个 |
|---|---|---|---|
| hap | HarmonyOS Ability Package | 应用模块 | ❌ |
| har | HarmonyOS Archive | 库模块 | ✅ 插件用这个 |
| hsp | HarmonyOS Shared Package | 共享模块 | ❌ |
Flutter插件必须用har类型,因为插件是作为库被应用引用的,而不是独立运行的应用。
4.4 设备类型配置
json5
"deviceTypes": [
"default", // 手机
"tablet" // 平板
// 还可以添加:
// "tv" // 智慧屏
// "wearable" // 穿戴设备
// "car" // 车载设备
]
flutter_speech目前只配置了手机和平板,因为语音识别主要在这两种设备上使用。如果你的插件需要支持更多设备类型,在这里添加即可。
4.5 权限声明(重要)
如果插件需要系统权限,需要在module.json5中声明。但对于flutter_speech来说,权限声明是在宿主应用的module.json5中,而不是插件的module.json5中:
json5
// 宿主应用的module.json5(不是插件的)
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.MICROPHONE",
"reason": "$string:microphone_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
}
}
⚠️ 这是一个容易搞混的地方:权限声明在宿主应用中,不在插件中。插件只负责在运行时动态申请权限。
五、index.ets 入口文件与插件导出
5.1 文件内容
typescript
import FlutterSpeechPlugin from './src/main/ets/components/plugin/FlutterSpeechPlugin';
export default FlutterSpeechPlugin;
就两行代码,但作用很关键:
- 导入 :从插件实现文件中导入
FlutterSpeechPlugin类 - 导出:将其作为模块的默认导出
5.2 为什么需要index.ets
index.ets是oh-package.json5中main字段指定的入口文件。Flutter-OHOS的构建系统会通过这个入口找到插件类,然后自动注册到Flutter引擎中。
oh-package.json5 ("main": "index.ets")
│
└── index.ets (export default FlutterSpeechPlugin)
│
└── FlutterSpeechPlugin.ets (插件实现)
如果没有index.ets,或者main字段指向了错误的文件,Flutter-OHOS就找不到插件类,插件就不会被注册。
5.3 导出方式的选择
ArkTS支持两种导出方式:
typescript
// 方式一:默认导出(flutter_speech用的)
export default FlutterSpeechPlugin;
// 方式二:命名导出
export { FlutterSpeechPlugin };
Flutter-OHOS的插件系统要求使用默认导出 (export default),不要用命名导出。
🤦 又一个坑 :我一开始用了命名导出
export { FlutterSpeechPlugin },结果插件注册失败。改成export default就好了。这种问题日志里也不会有明确的错误提示,只是插件默默地不工作。
六、从零创建ohos目录的完整步骤
6.1 手动创建步骤
如果你要从零开始为一个Flutter插件添加OpenHarmony支持,按照以下步骤操作:
bash
# 1. 在插件根目录下创建ohos目录结构
mkdir -p ohos/src/main/ets/components/plugin
# 2. 创建核心文件
touch ohos/oh-package.json5
touch ohos/build-profile.json5
touch ohos/index.ets
touch ohos/hvigorfile.ts
touch ohos/src/main/module.json5
touch ohos/src/main/ets/components/plugin/FlutterSpeechPlugin.ets
6.2 填充配置文件
oh-package.json5:
json5
{
"name": "flutter_speech",
"version": "1.0.0",
"description": "Flutter speech recognition plugin for OpenHarmony",
"main": "index.ets",
"author": "",
"license": "Apache-2.0",
"dependencies": {}
}
build-profile.json5:
json5
{
"apiType": "stageMode",
"buildOption": {
},
"targets": [
{
"name": "default"
}
]
}
module.json5:
json5
{
"module": {
"name": "flutter_speech",
"type": "har",
"deviceTypes": [
"default",
"tablet"
]
}
}
hvigorfile.ts:
typescript
export { harTasks } from '@ohos/hvigor-ohos-plugin';
index.ets:
typescript
import FlutterSpeechPlugin from './src/main/ets/components/plugin/FlutterSpeechPlugin';
export default FlutterSpeechPlugin;
6.3 更新pubspec.yaml
别忘了在pubspec.yaml中添加ohos平台声明:
yaml
flutter:
plugin:
platforms:
# ... 其他平台
ohos:
package: com.flutter.speech_recognition.flutter_speech
pluginClass: FlutterSpeechPlugin
6.4 验证工程结构
bash
# 检查目录结构是否正确
find ohos -type f | sort
# 预期输出:
# ohos/build-profile.json5
# ohos/hvigorfile.ts
# ohos/index.ets
# ohos/oh-package.json5
# ohos/src/main/ets/components/plugin/FlutterSpeechPlugin.ets
# ohos/src/main/module.json5
七、常见问题与排查
7.1 插件加载失败
症状:App编译成功但插件方法调用无响应
排查清单:
| 检查项 | 怎么检查 | 常见错误 |
|---|---|---|
| oh-package.json5的main字段 | 确认指向index.ets | 路径写错 |
| index.ets的导出方式 | 确认用export default | 用了命名导出 |
| pubspec.yaml的pluginClass | 确认和类名一致 | 拼写错误 |
| module.json5的type | 确认是"har" | 写成了"hap" |
| 类名一致性 | 三处类名必须一致 | 大小写不一致 |
三处类名必须一致:
yaml
# pubspec.yaml
pluginClass: FlutterSpeechPlugin
typescript
// index.ets
export default FlutterSpeechPlugin;
typescript
// FlutterSpeechPlugin.ets
export default class FlutterSpeechPlugin implements FlutterPlugin {
7.2 编译报错
常见编译错误及解决方案:
bash
# 错误1:找不到@ohos/flutter_ohos模块
# 原因:Flutter-OHOS SDK版本不对或未正确配置
# 解决:检查Flutter-OHOS SDK路径和版本
# 错误2:module.json5格式错误
# 原因:JSON5语法错误(多了逗号、少了引号等)
# 解决:用JSON5验证工具检查语法
# 错误3:oh-package.json5中name不匹配
# 原因:name和pubspec.yaml中的name不一致
# 解决:确保两处name完全相同
7.3 调试技巧
bash
# 查看详细编译日志
flutter run -d ohos --verbose
# 查看插件注册日志
hdc hilog | grep "FlutterSpeechPlugin"
# 查看ohpm依赖解析
cd ohos && ohpm install && ohpm list
八、工程创建检查清单
最后给大家一份完整的检查清单,创建完ohos目录后逐项确认:
-
ohos/oh-package.json5存在且main字段指向index.ets -
ohos/oh-package.json5的name和pubspec.yaml的name一致 -
ohos/build-profile.json5存在且apiType为stageMode -
ohos/src/main/module.json5存在且type为har -
ohos/index.ets存在且使用export default导出插件类 -
ohos/src/main/ets/components/plugin/FlutterSpeechPlugin.ets存在 -
pubspec.yaml中已添加ohos平台配置 -
pubspec.yaml中的pluginClass和实际类名一致 - 目录结构符合规范(src/main/ets/components/plugin/)
✅ 全部通过?恭喜! 插件工程创建完成,下一步就是编写核心插件代码了。
总结
本文详细讲解了OpenHarmony插件工程的创建过程:
- 目录结构 :遵循
src/main/ets/components/plugin/的标准路径 - oh-package.json5 :包配置文件,
main字段指向index.ets是关键 - build-profile.json5:构建配置,必须使用Stage模型
- module.json5 :模块声明,类型必须是
har - index.ets :入口文件,使用
export default导出插件类
下一篇我们将深入FlutterPlugin接口适配 ,讲解如何实现onAttachedToEngine、onDetachedFromEngine等生命周期方法。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源: