Skip to content

鸿蒙适配插件

使用 flutter-ohos(鸿蒙定制版 Flutter)开发时,很多 pub.dev 上的插件还没有适配鸿蒙平台。你可以下载插件源码到本地,自行添加鸿蒙平台支持

整体流程

1. 找到目标插件 ──> 2. 下载源码 ──> 3. 放入本地目录 ──> 4. 添加鸿蒙实现 ──> 5. 本地引用测试

第一步:找到目标插件

pubspec.yaml 中确认你要适配的插件名称和版本,然后在 pub.dev 或 GitHub 上找到它的源码仓库。

第二步:下载源码到本地

bash
# 方式一:git clone(推荐,方便后续更新和提交 PR)
cd my_app/plugins
git clone https://github.com/xxx/target_plugin.git

# 方式二:从 pub.dev 下载特定版本
cd my_app/plugins
# 在 pub.dev 的插件页面,点击 "Download" 下载 tar.gz,解压到目标目录

注意版本

下载的源码版本应与项目中原来使用的版本一致,避免引入不兼容的变更。使用 git clone 时可通过 git checkout v1.2.0 切换到对应标签。

第三步:修改引用方式

pubspec.yaml 中原来的远程依赖改为本地路径引用:

yaml
dependencies:
  # 原来的引用方式(注释掉或删除)
  # shared_preferences: ^2.2.0

  # 改为本地引用
  shared_preferences:
    path: plugins/shared_preferences

运行 flutter pub get 确认依赖正常解析。

第四步:添加鸿蒙平台实现

进入插件源码目录,添加鸿蒙平台支持:

1. 在 pubspec.yaml 中声明鸿蒙平台

打开插件的 pubspec.yaml,在插件配置中添加 harmony 平台:

yaml
# 插件的 pubspec.yaml
name: shared_preferences
# ...

# 如果插件使用的是旧的 plugin 格式,需要修改 flutter.plugin 部分
flutter:
  plugin:
    platforms:
      android:
        package: io.flutter.plugins.sharedpreferences
        pluginClass: SharedPreferencesPlugin
      ios:
        pluginClass: FLTSharedPreferencesPlugin
      harmony:                                    # 新增鸿蒙平台
        pluginClass: SharedPreferencesPlugin       # 鸿蒙端插件类名

2. 创建鸿蒙原生代码目录

bash
cd plugins/shared_preferences

# 创建鸿蒙平台目录结构
mkdir -p harmony/entry/src/main/ets

鸿蒙插件的标准目录结构:

harmony/
├── entry/
│   └── src/
│       └── main/
│           ├── ets/                # ArkTS 源码
│           │   └── XxxPlugin.ets   # 插件实现
│           └── module.json5        # 模块配置
├── oh-package.json5                # 鸿蒙依赖配置
├── hvigorfile.ts                   # 构建配置
└── BuildProfile.ets                # 构建配置

3. 实现鸿蒙端插件

参考插件的 Android/iOS 实现,用 ArkTS 编写鸿蒙端:

typescript
// harmony/entry/src/main/ets/SharedPreferencesPlugin.ets
import { MethodChannel, FlutterPlugin, FlutterPluginBinding } from '@ohos/flutter_ohos';

export class SharedPreferencesPlugin implements FlutterPlugin {
  private channel?: MethodChannel;

  getUniqueClassName(): string {
    return 'SharedPreferencesPlugin';
  }

  onAttachedToEngine(binding: FlutterPluginBinding): void {
    this.channel = new MethodChannel(binding.getBinaryMessenger(), 'plugins.flutter.io/shared_preferences');
    this.channel.setMethodCallHandler({
      onMethodCall: async (call, result) => {
        switch (call.method) {
          case 'getAll':
            // 实现获取所有偏好设置逻辑
            result.success({});
            break;
          case 'setString':
            // 实现设置字符串逻辑
            result.success(true);
            break;
          // ... 对照 Android/iOS 实现补全其他方法
          default:
            result.notImplemented();
        }
      }
    });
  }

  onDetachedFromEngine(binding: FlutterPluginBinding): void {
    this.channel?.setMethodCallHandler(null);
  }
}

4. 注册插件

创建入口文件,导出插件注册信息:

typescript
// harmony/entry/src/main/ets/Index.ets
export { SharedPreferencesPlugin } from './SharedPreferencesPlugin';

第五步:调试与验证

bash
# 在鸿蒙设备上运行,验证插件功能
flutter pub get
flutter run -d harmony

建议优先运行插件自带的 example/ 示例应用来验证,确认功能正常后再集成到主项目中。

适配建议

  • 对照实现:先仔细阅读 Android 端的实现逻辑,确保鸿蒙端行为一致
  • Channel 名称必须一致:Dart 端和原生端的 MethodChannel 名称必须完全相同
  • 方法名必须一致call.method 的值要和 Dart 端 invokeMethod 传入的方法名完全匹配
  • 渐进式适配:先实现核心方法,再逐步补全其他方法,每一步都做验证
  • 参考社区OpenHarmony-SIG 已有大量常用插件的鸿蒙适配,可以直接参考或复用

贡献回社区

如果你的适配具有通用性,可以考虑向上游提交 PR:

  1. Fork 原插件仓库
  2. 在 Fork 仓库中添加鸿蒙适配代码
  3. 提交 Pull Request

这样其他开发者也能受益于你的适配工作。

常见问题:DevEco Studio 打开 ohos 目录报错

错误信息

在 Windows 上克隆 flutter-ohos 的 Git 仓库后,用 DevEco Studio 打开 ohos 目录进行签名或构建时,可能会遇到以下报错:

hvigor ERROR: Error Cannot find module 'flutter-hvigor-plugin'
Require stack:
- D:\code-demo\flutter\demo\riverpod\ohos\hvigorconfig.ts

原因分析

当 DevEco Studio 打开 ohos 目录时,会执行 hvigorw --sync,hvigor 的模块查找流程如下:

  1. 读取 ohos/hvigor/hvigor-config.json5 中的 dependencies
  2. 安装这些依赖到 hvigor 缓存工作区 ~/.hvigor/project_caches/<hash>/workspace/node_modules/(使用 npm/pnpm)
  3. 设置 NODE_PATH 指向该缓存工作区的 node_modules
  4. hvigor 内置了 .ts 扩展处理器,用 TypeScript 的 transpileModule 运行时编译 .ts 文件,其 compilerOptions.baseUrl 也指向缓存工作区的 node_modules

核心问题:flutter-hvigor-plugin 虽然通过项目根目录的 package.json 被 npm 安装到了 ohos/node_modules/ 下,但 hvigor 查找模块的位置是它自己的缓存工作区 node_modules,而非项目目录下的 node_modules。由于 hvigor-config.json5dependencies 为空,hvigor 不会在缓存工作区安装 flutter-hvigor-plugin,导致 require('flutter-hvigor-plugin') 找不到模块。

解决方法

ohos/hvigor/hvigor-config.json5dependencies 中添加 flutter-hvigor-plugin,指向 Flutter SDK 中的插件路径。

修改前:

json5
{
  "modelVersion": "5.1.0",
  "dependencies": {
  }
}

修改后:

json5
{
  "modelVersion": "5.1.0",
  "dependencies": {
    "flutter-hvigor-plugin": "file:<Flutter SDK路径>/packages/flutter_tools/hvigor"
  }
}

以当前环境为例:

json5
{
  "modelVersion": "5.1.0",
  "dependencies": {
    "flutter-hvigor-plugin": "file:D:\\code-demo\\flutter\\version\\FlutterOH\\3.35.8-ohos-0.0.3\\packages\\flutter_tools\\hvigor"
  }
}

注意

请将 <Flutter SDK路径> 替换为你实际的 Flutter 鸿蒙版 SDK 路径。可通过 flutter --version 确认当前使用的 SDK 版本和位置。

修改完成后,重新用 DevEco Studio 打开项目,hvigor 会自动将 flutter-hvigor-plugin 安装到缓存工作区,错误即可消除。

基于 Flutter 官方文档整理