Flutter 3.47 鸿蒙三方库适配实战:从 0 到 1 让 appinio_social_share 写入鸿蒙剪贴板

一个三方分享插件通常同时包含很多平台能力:复制文本、系统分享、短信、Telegram、WhatsApp、Instagram 等。适配到鸿蒙时,不能因为其中几个第三方 App 没有直接对应的 Ability,就把整个插件判定为“无法适配”。更实际的做法是先拆能力,再把能稳定映射到鸿蒙的部分做好。

本文以 appinio_social_share 0.3.3 为例,选择其中的“复制文本到剪贴板”能力完成 Flutter 3.47 鸿蒙适配。文章重点记录适配过程:如何分析 Dart API,如何补充 OHOS 平台声明,如何注册 MethodChannel,如何调用鸿蒙 pasteboard API,以及如何在 API 26 真机上回读成功结果。

一、最终效果

图 1:API 26 真机启动适配后的 Demo。

图 2:点击复制按钮后,页面收到 Copied to OpenHarmony clipboard,说明 ArkTS 已经完成剪贴板写入。

验证点真机结果
Flutter3.47.4-ohos-1.0.4
HarmonyOS7.0.0.105,API 26
HAPsigned HAP 构建通过
Dart API新增 AppinioSocialShare.copyToClipBoard()
OHOS APIpasteboard.getSystemPasteboard().setData()
真机结果页面显示 Copied to OpenHarmony clipboard

二、先拆清楚这个库的能力

上游库的入口对象包含 Android 和 iOS 两组平台方法。原始代码中,复制方法最终会走到:

Future<String> copyToClipBoard(String message) {
  return AppinioSocialSharePlatform.instance
      .copyToClipBoard(message);
}

插件的通道名称是:

const MethodChannel('appinio_social_share');

这次没有试图一次实现所有第三方社交平台,而是先把能力分成三类:

能力类别鸿蒙处理
复制文本到系统剪贴板本文完成真实 OHOS 实现
系统分享面板保留通道,后续按 Want 分享能力继续接入
指定第三方 App 分享需要逐个确认目标 App 的鸿蒙 Ability,不能直接复用 Android 包名

这样做的好处是:适配结果可以精确描述到单个 API。读者能知道哪个能力已经跑通,哪个能力仍受平台差异影响。

三、准备 Flutter 3.47 和真机

本文实际环境:

工具版本
Flutter OH3.47.4-ohos-1.0.4
Dart3.13.3
DevEco Studio26.0.0 Release
HarmonyOS SDKAPI 26
测试设备127.0.0.1:5555,HarmonyOS 7.0.0.105

环境没有准备好时,先看 Flutter OH 环境搭建指南。

export PATH=/Users/von/Developer/flutter-oh-3.47.4/bin:$PATH
flutter --version
hdc list targets

确认 Flutter 版本包含 3.47.4-ohos,并确认 hdc list targets 能看到 ohos-arm64。公开文章截图中不要保留完整设备序列号。

四、拉取 AtomGit 适配分支

本文代码信息:

git clone https://atomgit.com/oh-flutter/appinio_social_share.git
cd appinio_social_share
git switch feat/ohos_appinio_social_share_0.3.3
git log -1 --oneline

先确认分支,再看 pubspec.yaml 中的包版本。不要在错误分支上直接生成 OHOS 目录,否则之后很难对照适配提交。

五、先分析原有 Dart 调用链

原插件使用平台接口类保存 MethodChannel 默认实现:

static AppinioSocialSharePlatform _instance =
    MethodChannelAppinioSocialShare();

static AppinioSocialSharePlatform get instance => _instance;

原插件的公开对象只暴露了 android 和 iOS 两个包装对象。为了让鸿蒙业务代码不用直接依赖内部 platform interface,我新增了两个通用方法:

class AppinioSocialShare {
  Future<String> copyToClipBoard(String message) {
    return AppinioSocialSharePlatform.instance.copyToClipBoard(message);
  }

  Future<String> shareToSystem(String title, String message) {
    return AppinioSocialSharePlatform.instance.shareToSystem(
      title,
      message,
    );
  }
}

这里的改动保持向下兼容:原来的 android 和 iOS 属性仍然保留,新增的方法只是给跨平台业务一个更直接的入口。

六、声明 OHOS 平台

在 pubspec.yaml 中增加:

flutter:
  plugin:
    platforms:
      android:
        package: appinio.social.share
        pluginClass: AppinioSocialSharePlugin
      ios:
        pluginClass: AppinioSocialSharePlugin
      ohos:
        pluginClass: AppinioSocialSharePlugin

OHOS 入口文件:

import AppinioSocialSharePlugin from './src/main/ets/components/plugin/AppinioSocialSharePlugin';

export default AppinioSocialSharePlugin;

原生实现文件位于:

ohos/src/main/ets/components/plugin/AppinioSocialSharePlugin.ets

到这里,Flutter 只知道“鸿蒙有这个插件”。下一步才是把具体方法接到系统服务。

七、把 Dart 方法映射到 ArkTS

Dart 端调用:

await methodChannel.invokeMethod<String>(
  'copy_to_clipboard',
  {'message': message},
);

ArkTS 端按相同方法名接收:

case 'copy_to_clipboard':
  this.copyToClipboard(call, result);
  return;

两边的通道名和方法名必须完全一致:

项目值
Channelappinio_social_share
Methodcopy_to_clipboard
参数message
返回值String
成功返回Copied to OpenHarmony clipboard

新手最容易犯的错误是只改 Dart 方法名,忘记同步 ArkTS 的 switch 分支。这样构建可能成功,但运行时会收到 notImplemented。

八、接入鸿蒙 pasteboard API

鸿蒙剪贴板 API 来自 @kit.BasicServicesKit:

import { pasteboard } from '@kit.BasicServicesKit';

实际写入过程分成三步:

const data = pasteboard.createData(
  pasteboard.MIMETYPE_TEXT_PLAIN,
  message,
);
const board = pasteboard.getSystemPasteboard();
await board.setData(data);
result.success('Copied to OpenHarmony clipboard');

每一步的含义如下:

  1. createData 把 Dart 字符串包装成鸿蒙剪贴板数据。
  2. MIMETYPE_TEXT_PLAIN 表示这是一段普通文本。
  3. getSystemPasteboard 获取系统剪贴板。
  4. setData 写入数据。

参数为空时,不应该把 undefined 传给系统 API:

if (message === undefined) {
  result.error('INVALID_ARGUMENT', 'message is required.', null);
  return;
}

系统调用失败时返回明确错误码:

catch (error) {
  result.error('CLIPBOARD_ERROR', `${error}`, null);
}

这样 Dart 层可以捕获 PlatformException,业务决定是否重试。

九、创建最小可复现 Demo

Demo 只保留一个复制按钮:

Future<void> _copy() async {
  final result = await _share.copyToClipBoard(
    'Flutter 3.47 OpenHarmony',
  );
  if (!mounted) return;
  setState(() => _status = result);
}

这里没有使用文件选择器、图片路径或第三方社交 App,原因是本文只验证文本剪贴板这条最小链路。最小 Demo 更容易判断问题发生在 Dart、通道还是原生 API。

十、构建和签名

先执行无签名构建:

flutter pub get
flutter analyze
cd example
flutter test
flutter build hap --debug --no-codesign

本文 Demo 原始示例包含 file_picker,它会带来 Linux、macOS、Windows 的插件提示。鸿蒙构建并不需要这些桌面能力;真正需要确认的是 OHOS ArkTS 编译和 HAP 生成。

打开 example/ohos 配置调试签名,再执行:

flutter build hap --debug
hdc list targets
hdc install -r build/ohos/hap/entry-default-signed.hap
hdc shell aa start -a EntryAbility -b com.example.flutter_oh_demo

不要把证书文件、密码、本机签名路径提交到 AtomGit。

十一、真机验证

启动后页面显示“尚未复制”。点击“复制到鸿蒙剪贴板”后,页面显示:

Copied to OpenHarmony clipboard

这个结果表示:

  • Flutter 页面调用了新增的 Dart API。
  • MethodChannel 成功到达 ArkTS。
  • ArkTS 成功创建文本 PasteData。
  • 系统剪贴板写入没有抛出异常。

本文只把“文本复制”记为通过。指定 Instagram、Telegram、WhatsApp 等第三方应用的分享,还需要分别确认鸿蒙端是否存在对应 Ability,不能因为系统剪贴板成功就宣称所有社交分享都完成。

十二、常见问题

Q1:为什么要在 AppinioSocialShare 外面再加一个方法

原库主要按 Android 和 iOS 两个平台组织 API。新增通用方法可以让鸿蒙业务直接调用,不需要业务方理解内部 platform interface,也不会破坏原有 Android/iOS 包装对象。

Q2:为什么不能直接复用 Android 分享代码

Android 分享依赖 Intent 和 Android 包名。鸿蒙使用 Want/Ability 模型,第三方应用的包名、Action 和 URI 规则都可能不同,直接复制 Android 实现会得到一个能编译但不能工作的假适配。

Q3:剪贴板写入后如何证明成功

本文用 MethodChannel 返回结果和真机页面状态作为第一层证据。需要更强的回读测试时,可以在独立验证宿主中调用鸿蒙 pasteboard 的读取 API,再比较写入文本。

Q4:出现 notImplemented 怎么排查

按顺序检查:pubspec.yaml 是否声明 ohos,ohos/index.ets 是否导出正确类名,Channel 是否都是 appinio_social_share,Method 是否都是 copy_to_clipboard,最后重新安装 HAP。

十三、复现命令

git clone https://atomgit.com/oh-flutter/appinio_social_share.git
cd appinio_social_share
git switch feat/ohos_appinio_social_share_0.3.3
export PATH=/Users/von/Developer/flutter-oh-3.47.4/bin:$PATH
flutter pub get
flutter analyze
cd example
flutter test
flutter build hap --debug --no-codesign

十四、总结

这次适配先把复杂的社交分享能力拆开,选择最稳定的文本剪贴板作为第一条鸿蒙实现链路。Dart API、MethodChannel、ArkTS 插件注册和鸿蒙系统 API 四层都保留了清晰边界,真机结果也能对应到具体方法。后续新增系统分享面板或第三方应用跳转时,可以沿用同一套分析方法,但必须为每种能力单独做 API 和真机验证。

十五、参考资料与仓库地址

本文适配仓库

上游和包信息

Flutter 和鸿蒙资料

欢迎加入CPF-Flutter 鸿蒙社区:https://atomgit.com/CPF-Flutter

Logo

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

更多推荐