Flutter/OpenHarmony 三方库适配实战:tuya_home_flutter_plugin家庭通道
Flutter/OpenHarmony 三方库适配实战:tuya_home_flutter_plugin家庭通道
一、项目信息
| 项目 | 内容 |
|---|---|
| 仓库名称 | tuya_home_flutter_plugin |
| Dart 包名 | tuya_home_sdk_flutter |
| AtomGit 仓库地址 | https://atomgit.com/oh-flutter/tuya_home_flutter_plugin |
| 上游适配版本 | 0.0.1 |
| OHOS 适配版本 | 0.0.1-ohos.1 |
| 方法通道 | tuya_home_sdk_flutter |
| 事件通道 | DPS、设备发现、Wi-Fi 发现各一条 |
| OHOS 原生入口 | TuyaHomeSdkFlutterPlugin |
| 示例包名 | com.example.tuya_home_sdk_flutter_example |
| HAP 产物 | example/build/ohos/hap/entry-default-unsigned.hap |
| 当前状态 | 本地已完成分析、测试、构建和模拟器启动验证,目标仓库已创建 |
任务名称使用 tuya_home_flutter_plugin_ohos,但 pubspec.yaml 的包名
必须保持上游真实名称 tuya_home_sdk_flutter。改包名会破坏所有 import 和
依赖解析,因此只在仓库命名层区分。
目标 AtomGit 仓库已创建,适配代码将提交到 main 分支。
二、为什么不能直接“把方法都返回 true”
上游 Dart 层覆盖了大量家庭业务:
账号 注册、登录、验证码、密码重置、用户资料
家庭 创建、更新、删除、查询、Token
房间 创建、更新、删除、查询
设备 查询、删除、重命名、DPS 下发
配网 BLE+Wi-Fi、Wi-Fi、有线、子设备
成员 添加、查询、删除、修改
邀请 加入、取消、接受/拒绝、查询、修改
事件 设备 DPS、设备发现、Wi-Fi 设备发现
这些方法背后依赖涂鸦账号服务、家庭服务、配网协议和设备事件服务。当前
OpenHarmony 没有可验证的对应原生 SDK。如果 OHOS 插件把所有方法都返回
true,调用方会认为家庭和设备已经创建,随后却拿不到任何真实数据,错误
会扩散到数据库、UI 和业务状态机。
本次选择的边界是:
- 完整保留 Dart API 和通道名,方便未来接入 SDK。
- OHOS 实现平台版本和适配版本查询。
- 其他方法返回
tuya_home_unsupported。 - 三个 EventChannel 主动返回 unsupported,不伪造事件。
三、上游通道契约
Dart 单例固定使用一条方法通道:
class TuyaHomeSdkFlutter {
final methodChannel =
const MethodChannel('tuya_home_sdk_flutter');
static TuyaHomeSdkFlutter get instance {
return _singleton ??= TuyaHomeSdkFlutter._();
}
另外还有三条事件通道:
final _deviceEvent = const EventChannel(
'tuya_home_sdk_flutter_device_dps_event',
);
final _deviceDiscoveryEvent = const EventChannel(
'tuya_home_sdk_flutter_device_discovery_event',
);
final EventChannel _wifiEvent = const EventChannel(
'tuya_home_sdk_flutter_wifi_discovery_event',
);
这意味着 OHOS 适配至少要注册四条通道。只注册 MethodChannel 时,账号和
家庭方法会得到错误,但三个流可能表现为“永远没有数据”,业务很难区分
“无设备”和“原生流没有实现”。
四、让 Flutter OHOS 发现插件
根 pubspec.yaml:
name: tuya_home_sdk_flutter
version: 0.0.1-ohos.1
flutter:
plugin:
platforms:
android:
package: com.example.tuya_home_sdk_flutter
pluginClass: TuyaHomeSdkFlutterPlugin
ios:
pluginClass: TuyaHomeSdkFlutterPlugin
ohos:
pluginClass: TuyaHomeSdkFlutterPlugin
OHOS HAR 的 hvigorfile.ts:
import { harTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: harTasks,
plugins: [],
};
index.ets:
import TuyaHomeSdkFlutterPlugin
from './src/main/ets/components/plugin/TuyaHomeSdkFlutterPlugin';
export default TuyaHomeSdkFlutterPlugin;
oh-package.json5 将模块类型约束为 HAR:
{
"module": {
"name": "tuya_home_sdk_flutter",
"type": "har",
"deviceTypes": ["default", "tablet"]
}
}
五、ArkTS 注册一条方法通道和三条事件通道
插件实现 FlutterPlugin、MethodCallHandler 和 StreamHandler:
export default class TuyaHomeSdkFlutterPlugin
implements FlutterPlugin, MethodCallHandler, StreamHandler {
private methodChannel: MethodChannel | null = null;
private deviceDpsChannel: EventChannel | null = null;
private discoveryChannel: EventChannel | null = null;
private wifiChannel: EventChannel | null = null;
onAttachedToEngine(binding: FlutterPluginBinding): void {
this.methodChannel = new MethodChannel(
binding.getBinaryMessenger(),
'tuya_home_sdk_flutter',
);
}
实际实现中 MethodChannel 和 EventChannel 分别创建。注册完成后,方法调用
入口只开放两个已验证分支:
onMethodCall(call: MethodCall, result: MethodResult): void {
switch (call.method) {
case 'getPlatformVersion':
result.success('OHOS');
return;
case 'getSDKVersion':
result.success(
'tuya_home_sdk_flutter OHOS adapter 0.0.1-ohos.1',
);
return;
default:
result.error(
'tuya_home_unsupported',
`${call.method}: Tuya Home SDK is not available on OpenHarmony.`,
null,
);
return;
}
}
事件监听主动报错:
onListen(args: Any, events: EventSink): void {
events.error(
'tuya_home_unsupported',
'Tuya Home SDK is not available on OpenHarmony.',
null,
);
}
引擎销毁时必须卸载三个流处理器:
onDetachedFromEngine(binding: FlutterPluginBinding): void {
this.removeStreamHandlers();
this.methodChannel?.setMethodCallHandler(null);
this.methodChannel = null;
this.deviceDpsChannel = null;
this.discoveryChannel = null;
this.wifiChannel = null;
}
如果不清理,Flutter Engine 重建后可能继续持有旧 handler,导致回调进入
已经销毁的 Dart isolate。
六、平台版本接口与业务单例
上游模板只在 platform interface 中实现 getPlatformVersion,但示例页面
直接使用 TuyaHomeSdkFlutter(),该构造函数并不存在。本次增加单例访问:
class TuyaHomeSdkFlutter {
static TuyaHomeSdkFlutter? _singleton;
static TuyaHomeSdkFlutter get instance {
return _singleton ??= TuyaHomeSdkFlutter._();
}
Future<String?> getPlatformVersion() {
return TuyaHomeSdkFlutterPlatform.instance
.getPlatformVersion();
}
示例改为:
final _tuyaHomeSdkFlutterPlugin =
TuyaHomeSdkFlutter.instance;
final String platformVersion =
await _tuyaHomeSdkFlutterPlugin.getPlatformVersion() ??
'Unknown platform version';
这条修复让 OHOS 注册结果真正显示在示例页面,而不是停留在模板的
Unknown。
七、同步修复上游 Dart 问题
适配时处理了几个与 OHOS 运行相关的问题:
1. 房间匹配错误
// 修改前
if (room == roomId) {
return room;
}
// 修改后
if (room.id == roomId) {
return room;
}
原写法比较的是模型对象和整数 ID,条件永远不可靠。
2. 无效的空值合并
// 移除无意义的 ?? null
schemaModel.toJson();
3. 清理不必要 import
多个模型文件删除未使用 import,避免 flutter analyze 产生噪声。
4. 示例构造函数修复
将不存在的 TuyaHomeSdkFlutter() 改为
TuyaHomeSdkFlutter.instance。
这些修复不等于实现了涂鸦业务,但它们保证插件注册、版本查询和示例页面
是真实可运行的。
八、业务 API 的 OHOS 行为
| API 分组 | 上游示例 | OHOS 当前行为 |
|---|---|---|
getPlatformVersion | 查询平台 | 成功返回 OHOS |
initSdk | 初始化涂鸦 SDK | tuya_home_unsupported |
| 注册、登录、验证码 | 账号服务 | tuya_home_unsupported |
| 家庭、房间、成员、邀请 | 家庭服务 | tuya_home_unsupported |
| 设备查询、删除、重命名 | 设备服务 | tuya_home_unsupported |
| 配网四类接口 | 配网协议 | tuya_home_unsupported |
| DPS 下发 | 设备控制 | tuya_home_unsupported |
| 三个事件流 | 原生事件 | Stream 错误返回 unsupported |
业务端可以统一处理:
Future<T> runTuyaAction<T>(
Future<T> Function() action,
) async {
try {
return await action();
} on PlatformException catch (error) {
if (error.code == 'tuya_home_unsupported') {
throw UnsupportedError(
'当前 OpenHarmony 版本尚未接入 Tuya Home SDK',
);
}
rethrow;
}
}
这样既能保留上游调用,也不会把“未实现”误判为“业务返回 false”。
九、示例页面与真实截图
示例通过平台版本调用验证插件注册:
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Plugin example app')),
body: Center(
child: Text('Running on: $_platformVersion\n'),
),
),
);
}
模拟器真实截图:

图 1:OpenHarmony 模拟器上的 tuya_home_sdk_flutter 示例。首屏已完成
渲染,插件版本查询结果由 MethodChannel 返回。
截图只用于证明插件注册和 Dart 页面运行,不表示涂鸦家庭业务已经接通。
十、HAP 构建与自动化测试
核心命令:
flutter analyze
flutter test
cd example
flutter analyze
flutter test
flutter build hap --debug --no-codesign
结果:
| 检查项 | 结果 |
|---|---|
| 根包 analyze | 通过,No issues found |
| 根包测试 | 通过 |
| 示例 analyze | 通过,No issues found |
| 示例测试 | 通过 |
| HAP 构建 | 通过 |
| 产物 | entry-default-unsigned.hap |
模拟器安装:
hdc install -r \
example/build/ohos/hap/entry-default-unsigned.hap
hdc shell aa start \
-a EntryAbility \
-b com.example.tuya_home_sdk_flutter_example
最终真实日志:
install bundle successfully.
start ability successfully.
20020081 4284 ... com.example.tuya_home_sdk_flutter_example
10-19 01:08:27.595 4284 4284 D ... Flutter:
FlutterNapi --> called onFirstFrame isPreload:0
进程 4284 完成首帧并稳定存活。
十一、LowMemoryKill 不是插件崩溃
验证过程中,多个 Flutter 示例同时驻留时,系统出现:
reason=LowMemoryKill
exit with signal:9
该事件的特点:
- 没有新增该应用的 cppcrash 文件。
- 日志由
memmgrservice明确标记为 LowMemoryKill。 - 4 GB 模拟器同时运行多个 Flutter 示例时更容易触发。
处理方式:
hdc shell aa force-stop com.example.jpush_example
hdc shell aa force-stop io.openinstall.openinstall_flutter_plugin_example
hdc shell reboot
重启模拟器后卸载旧包、单独安装 Tuya 示例,再启动并验证 onFirstFrame。
这个问题与 ArkTS 空指针、SIGSEGV 或插件异常不同,不能混为一类。
十二、接入真实 OHOS SDK 前的工程准备
未来接入涂鸦 SDK 时,应按以下顺序推进:
- 确认涂鸦提供 OpenHarmony Home SDK、版本、协议和包管理方式。
- 在
ohos/oh-package.json5中固定真实 SDK 依赖。 - 先实现
initSDK,验证 appKey、appSecret 和错误码。 - 再实现登录与用户信息,确认账号区域和验证码服务。
- 实现家庭和房间查询,验证模型 JSON 转换。
- 实现设备查询和 DPS,验证真实设备。
- 实现配网与三个 EventChannel,验证蓝牙、Wi-Fi 权限和生命周期。
- 最后补真机截图、设备日志和失败用例。
不能先批量把 switch 分支改成 result.success(true),否则后续 SDK 接入
时无法区分旧假成功和真实服务结果。
十三、目录结构
tuya_home_flutter_plugin_ohos/
├── lib/
│ ├── tuya_home_sdk_flutter.dart
│ ├── tuya_home_sdk_flutter_method_channel.dart
│ ├── tuya_home_sdk_flutter_platform_interface.dart
│ └── src/
│ ├── models/
│ └── tuya_home_sdk_flutter.dart
├── ohos/
│ ├── build-profile.json5
│ ├── hvigorfile.ts
│ ├── index.ets
│ └── src/main/ets/components/plugin/
│ └── TuyaHomeSdkFlutterPlugin.ets
├── example/
│ ├── lib/main.dart
│ └── ohos/
├── test/tuya_home_sdk_flutter_test.dart
├── photos/tuya_home_ohos.jpeg
├── verification.md
├── CHANGELOG.md
└── README.md
十四、总结
这次适配把一个大体量 Dart SDK 拆成了清晰的工程事实:
完整 Dart API 和模型
|
v
一条 MethodChannel + 三条 EventChannel
|
v
OHOS 插件注册和生命周期
|
+--> 可验证:平台版本、适配版本
+--> 暂不可验证:家庭业务和事件
|
v
analyze + test + HAP + 首帧 + 进程存活
适配完成的标准不是所有按钮都返回成功,而是工程可运行、通道可诊断、能力
边界真实、后续 SDK 接入路径明确。
仓库名称:tuya_home_flutter_plugin
仓库地址:https://atomgit.com/oh-flutter/tuya_home_flutter_plugin
欢迎加入 CPF-Flutter 社区,一起交流
Flutter 三方库 OpenHarmony 适配、家庭设备服务和 EventChannel 验证经验:
https://atomgit.com/CPF-Flutter
更多推荐



所有评论(0)