用户反馈组件是一条典型的“SDK 型”三方库:flutter_usabilla 的职责是把应用连到 Usabilla 的反馈后台——初始化、灌入自定义变量、按事件触发反馈表单、读取数据遮罩配置。它的所有真实能力都在 Usabilla 的原生 SDK 里。把它带到鸿蒙时,同样的问题先摆出来:Usabilla 没有面向 HarmonyOS 的原生 SDK,所以适配要做的是把通道契约补全,并把“哪些能力可用、哪些不可用”写清楚。

本文以 flutter_usabilla 2.6.1 为例,记录我如何注册插件通道、在 HarmonyOS API 26 模拟器上完成构建、安装、启动和调用验证,以及示例工程如何从依赖重型的上游演示收敛成鸿蒙工具链可构建的最小验证页。

适配仓库: oh-flutter/flutter_usabilla

适配分支: feat/ohos_flutter_usabilla_2.6.1

适配 TAG: 2.6.1-ohos.1

一、先看最终效果

图 1:HarmonyOS API 26 模拟器启动 Demo。页面显示插件返回的 OpenHarmony 3.47.4,状态为等待操作。

图 2:点击“初始化反馈组件”后的真实结果。initialize 调用完成。

验证点实测结果证据
Flutter OH 3.47 工程构建通过entry-default-signed.hap
签名、安装和启动通过图 1
getPlatformVersion返回 OpenHarmony 3.47.4图 1
initialize调用完成图 2
sendEvent调用完成,返回 null图 3
dismiss调用完成图 4
真实反馈表单依赖 Usabilla 原生 SDK 接入适配边界

继续在模拟器上点击其余两个按钮:

图 3:调用 sendEvent('ohos_demo_event') 后返回 null(可空返回类型),页面状态正常。

图 4:调用 dismiss() 后返回完成,反馈窗口生命周期调用不中断。

二、这个库原来是怎么工作的

flutter_usabilla 的 Dart 层是纯静态方法集合,通过名为 flutter_usabilla 的 MethodChannel 与原生 SDK 通信:

Dart FlutterUsabilla(静态方法)
  -> MethodChannel('flutter_usabilla')
  -> Usabilla 原生 SDK(Android / iOS)
  -> 反馈表单、事件上报、数据遮罩

几个关键方法的形态值得记录:initialize(appId) 只接收应用 ID;sendEvent(event) 返回一个 Map;getDefaultDataMasks 返回列表。这些返回形状都来自原生 SDK 的语义——本次适配在鸿蒙端保持同样的返回形状(空 Map、空列表),保证 Dart 侧的类型转换不会因为平台不同而崩。

和其他 SDK 型库一样,这里也延续了“无状态动作保持控制流”的策略:initialize、dismiss、sendEvent 如果抛异常,业务代码在所有调用点都要做平台特判;而这些调用的失败对主业务无影响,因此鸿蒙端返回完成并把边界写入文档。

三、实际环境

Flutter 鸿蒙环境搭建不在本文重复展开,直接参考 Flutter OH 环境搭建指南。

组件版本
Flutter OH3.47.4-ohos-1.0.4
Dart3.13.3
DevEco Studio26.0.0 Release
HarmonyOS SDKAPI 26
测试设备DevEco 模拟器 Pura X View(HarmonyOS 7.0.0.105,API 26)

本次验证使用 DevEco Studio 26.0.0 自带的 Pura X View 模拟器,系统版本与目标真机同为 HarmonyOS 7.0.0.105 / API 26;HAP 的签名、安装与启动链路和真机一致。
| 目标库 | flutter_usabilla 2.6.1 |

四、确认上游版本并同步到 AtomGit

上游包地址是 GitHub usabilla/usabilla-u4a-flutter,版本 2.6.1 使用 MIT License。适配前我在 AtomGit 目标组织中搜索了同名库,没有找到可以直接使用的 OHOS 实现。

仓库初始适配提交为 16a3c02,完成后分支最新提交为 c7492be。

git clone https://atomgit.com/oh-flutter/flutter_usabilla.git
cd flutter_usabilla
git switch feat/ohos_flutter_usabilla_2.6.1
git log --oneline -5

五、创建适配分支并检查工程结构

git switch -c feat/ohos_flutter_usabilla_2.6.1

关键目录如下:

flutter_usabilla/
├── lib/
│   ├── flutter_usabilla.dart                   # 全部静态方法
│   └── flutter_usabilla_method_channel.dart    # 平台接口通道
├── ohos/
│   ├── index.ets                               # OHOS 插件导出入口
│   └── src/main/ets/components/plugin/
│       └── FlutterUsabillaPlugin.ets           # MethodChannel 实现
├── example/lib/main.dart                        # 上机验证 Demo
├── pubspec.yaml                                # 声明 ohos 平台
└── README.OpenHarmony_CN.md                    # 鸿蒙适配说明

六、适配过程:返回形状对齐

OHOS 插件实现:

onAttachedToEngine(binding: FlutterPluginBinding): void {
  this.channel?.setMethodCallHandler(null);
  this.channel = new MethodChannel(binding.getBinaryMessenger(), 'flutter_usabilla');
  this.channel.setMethodCallHandler(this);
}

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

方法映射:

Dart 方法返回形状OHOS 本次策略
getPlatformVersionString返回 OpenHarmony 3.47.4
initializevoid返回成功
dismissvoid返回成功
sendEventMap?返回 null(可空返回,形状兼容)
getDefaultDataMasksList?返回空列表(对齐返回形状)
onMethodCall(call: MethodCall, result: MethodResult): void {
  switch (call.method) {
    case 'getPlatformVersion':
      result.success('OpenHarmony 3.47.4');
      return;
    case 'initialize':
      result.success(null);
      return;
    case 'dismiss':
      result.success(null);
      return;
    case 'sendEvent':
      result.success(null);
      return;
    case 'getDefaultDataMasks':
      result.success([]);
      return;
    default:
      result.notImplemented();
  }
}

sendEvent 和 getDefaultDataMasks 这两个返回形状是适配里的关键细节:sendEvent 在 Dart 声明为 Map?,鸿蒙端返回 null 表示“没有数据”,调用方做空值判断即可;getDefaultDataMasks 声明为可空列表,返回空列表保证遍历安全。形状与 Android/iOS 的语义对齐,调用方不需要为鸿蒙特判。

示例工程方面,上游的演示依赖 flutter_usabilla 示例自带的品牌化界面和配置模块;我把示例收敛成一个四按钮验证页(初始化、发送事件、关闭),同时把 example/pubspec.yaml 的 SDK 约束从早期的 >=2.12 提升到 >=3.0.0,与 Flutter OH 3.47 工具链对齐。

七、构建配置与签名

示例工程的目标 SDK 对齐到 26,AppScope/app.json5 统一成 com.example.flutter_oh_demo,与 DevEco 调试签名对应。

{
  "name": "default",
  "compatibleSdkVersion": "26.0.0",
  "targetSdkVersion": "26.0.0",
  "runtimeOS": "HarmonyOS"
}

八、通过 AtomGit 引入适配版

dependencies:
  flutter_usabilla:
    git:
      url: https://atomgit.com/oh-flutter/flutter_usabilla.git
      ref: 2.6.1-ohos.1

九、构建、安装和设备验证

cd example
flutter pub get
flutter analyze
flutter build hap --debug
hdc install -r build/ohos/hap/entry-default-signed.hap
hdc shell aa start -a EntryAbility -b com.example.flutter_oh_demo

构建输出为 ✓ Built build/ohos/hap/entry-default-signed.hap.,随后安装启动成功。模拟器上依次点击三个按钮得到图 2 至图 4,全部调用完成且无异常。

十、适配结果和当前边界

层次已完成内容尚未完成内容
Dart API保留全部静态方法无
MethodChannel通道名与方法名对齐无
OHOS 插件注册、版本查询、返回形状对齐Usabilla 原生 SDK 接入
示例工程四按钮验证页,SDK 约束升级到 3.x上游品牌化演示
文档README.OpenHarmony_CN.md、CHANGELOG无

反馈表单和事件上报的接入是后续工作:需要确认 Usabilla 是否发布 HarmonyOS SDK,或者把反馈链路改接到鸿蒙侧的等价方案。当前适配保证应用在鸿蒙上正常启动运行,initialize/dismiss 等生命周期调用稳定完成,返回形状与 Android/iOS 一致。

十一、FAQ

Q1:initialize 返回成功后,反馈表单能弹出来吗?

  • 现象: initialize 调用完成,但触发反馈表单不会有任何界面出现。
  • 原因: 鸿蒙端没有接入 Usabilla 原生 SDK,方法为契约实现。
  • 解决方法: 接入前不要依赖真实表单;以 README 声明的边界为准。
  • 验证结果: 图 2 是调用完成的真实页面状态。

Q2:sendEvent 返回的 Map 里为什么是空的?

  • 现象: sendEvent 返回了 Map,但内容为空。
  • 原因: 空 Map 是对齐返回形状的占位:保证 Dart 侧类型转换正确的同时语义上表示“没有数据”。
  • 解决方法: 业务方做空值处理;鸿蒙端上报数据需等原生 SDK 接入。
  • 验证结果: 图 3 显示调用完成后页面正常。

Q3:为什么升级了示例的 SDK 约束?

  • 现象: example/pubspec.yaml 的 sdk 约束从 >=2.12 提到 >=3.0.0。
  • 原因: Flutter OH 3.47 的 Dart 是 3.13.3,示例中的旧语法(无 super 参数等)在新工具链下会产生实验性语法错误。
  • 解决方法: 对齐约束并让 flutter analyze 全量通过。
  • 验证结果: analyze 与 signed HAP 构建均通过。

十二、总结

这次适配为 flutter_usabilla 2.6.1 补齐了 OHOS 插件注册和方法映射,保持返回形状与上游一致,示例工程收敛为鸿蒙工具链可构建的验证页。Demo 通过 Flutter OH 3.47.4 构建成签名 HAP,在 HarmonyOS API 26 模拟器上完成安装、启动和调用验证。

当前成果是“契约完整、边界明确”的适配基线。适配代码和说明都在 AtomGit 适配分支,复现时建议锁定 2.6.1-ohos.1 TAG。

十三、参考资料和仓库地址

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

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐