Android、iOS 都正常,到了 HarmonyOS 直接报 MissingPlugin,插件到底去哪了?

文章封面

做 Flutter 三方插件的时候,最开始的思路很简单:Android 有实现,iOS 有实现,复制一份到 HarmonyOS 不就行了?

结果真做的时候发现不对:Dart 层调用一个方法,直接抛 MissingPluginException。意思是"我找不到这个插件的 HarmonyOS 实现"。

这时候才意识到:插件不是"代码复制过去就行"。HarmonyOS 根本不知道有这个插件。

一、先想清楚:Flutter Plugin 的结构是什么

先把最基础的问题想明白。

一个 Flutter Plugin 不是一个文件夹,是好几层:

内容
Dart 层Dart 接口,给调用方用
平台实现层Android/iOS/HarmonyOS 的原生实现
example示例工程,用来测试

Dart 层是统一的。平台实现层,每个平台一份。

二、MissingPluginException 是什么意思

MissingPluginException 就是"找不到这个插件的平台实现"。

Dart 层调用一个方法,Flutter 引擎要找到对应的平台实现。找不到,就抛这个错。

为什么找不到?因为 HarmonyOS 模块根本没注册这个插件。

这段代码解决什么问题: 插件注册。
文件: ohos/src/main/ets/entryability/EntryAbility.ets
用途: HarmonyOS 插件注册
接入位置: Ability 初始化

import { FlutterAbility, FlutterPluginRegistry } from '@ohos/flutter';

export default class EntryAbility extends FlutterAbility {
  onCreate(want, launchParam) {
    super.onCreate(want, launchParam);
    
    // 注册插件
    let registry: FlutterPluginRegistry = this.getPluginRegistry();
    registry.regist(new MyPlugin());
  }
}

三、插件目录应该长什么样

一个标准的 Flutter Plugin 目录:

my_plugin/
├── lib/              # Dart 层
├── android/          # Android 实现
├── ios/              # iOS 实现
├── ohos/             # HarmonyOS 实现
├── example/          # 示例工程
└── pubspec.yaml      # 插件配置

ohos 目录就是 HarmonyOS 的实现。没有这个目录,或者没注册,就报 MissingPlugin。

插件目录图

四、为什么把 Android 代码复制一份行不通

很多人以为:Android 代码是 Java/Kotlin,复制过来翻译成 ArkTS 不就行了?

不对。不是语法翻译的问题。是架构和 API 都不一样。

对比AndroidHarmonyOS
语言Kotlin/JavaArkTS
组件Activity/FragmentUIAbility
APIAndroid SDKHarmonyOS Kit
通信MethodChannelMethodChannel(类似)

看起来类似,但细节全不一样。直接翻译过去,根本跑不起来。

五、几个容易踩的坑

第一个坑:只改 Dart 层,不改平台层。Dart 层改了,平台层没实现。

第二个坑:ohos 模块没有正确注册。插件写了,但没注册。

第三个坑:插件名和 Channel 名不一致。Dart 层和 ArkTS 层用的名字对不上。

第四个坑:example 能跑就认为主工程一定能用。example 和主工程配置可能不一样。

第五个坑:把 Android 平台代码机械翻译成 ArkTS。架构都不一样,翻译没用。

测试效果图

这次做插件移植最大的体会是:MissingPlugin 不是"代码写错了",是"插件根本没被识别"。

真正做的时候,最容易忽略的不是怎么写实现,而是怎么让系统知道有这个插件。注册、目录、命名,每一层都要对上。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐