Flutter三方库适配OpenHarmony【flutter_speech】— OpenHarmony 插件工程创建

前言

欢迎加入开源鸿蒙跨平台社区: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;

就两行代码,但作用很关键:

  1. 导入 :从插件实现文件中导入FlutterSpeechPlugin
  2. 导出:将其作为模块的默认导出

5.2 为什么需要index.ets

index.etsoh-package.json5main字段指定的入口文件。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.json5namepubspec.yamlname 一致
  • ohos/build-profile.json5 存在且 apiTypestageMode
  • ohos/src/main/module.json5 存在且 typehar
  • 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插件工程的创建过程:

  1. 目录结构 :遵循src/main/ets/components/plugin/的标准路径
  2. oh-package.json5 :包配置文件,main字段指向index.ets是关键
  3. build-profile.json5:构建配置,必须使用Stage模型
  4. module.json5 :模块声明,类型必须是har
  5. index.ets :入口文件,使用export default导出插件类

下一篇我们将深入FlutterPlugin接口适配 ,讲解如何实现onAttachedToEngineonDetachedFromEngine等生命周期方法。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

相关推荐
松叶似针1 小时前
Flutter三方库适配OpenHarmony【secure_application】— MethodChannel 通信协议设计
flutter·harmonyos
嘴贱欠吻!2 小时前
Flutter鸿蒙开发指南(十二):推荐列表数据获取
windows·flutter
嘴贱欠吻!2 小时前
Flutter鸿蒙开发指南(十三):推荐列表上拉加载
flutter
键盘鼓手苏苏2 小时前
Flutter for OpenHarmony:debounce_throttle 防抖与节流的艺术(优化用户交互与网络请求) 深度解析与鸿蒙适配指南
网络·flutter·交互
无巧不成书02183 小时前
Kotlin Multiplatform(KMP)核心解析
android·开发语言·kotlin·交互·harmonyos
Swift社区3 小时前
鸿蒙 PC 的最终形态:系统协作
华为·harmonyos
阿林来了3 小时前
Flutter三方库适配OpenHarmony【flutter_speech】— 语音识别监听器实现
人工智能·flutter·语音识别·harmonyos
松叶似针3 小时前
Flutter三方库适配OpenHarmony【secure_application】— setWindowPrivacyMode 隐私模式实现
flutter·harmonyos
tIjJrDKv3 小时前
自动驾驶汽车轨迹规划:人工势场法与MPC联合仿真探索
harmonyos