Flutter 想在 OpenHarmony 上跑起来,第一步不是写代码,而是搞清楚你到底在给谁写代码。这周我正好把去年折腾 Flutter for OpenHarmony 环境的过程整理了一遍,配合实战营 DAY 1 的节奏,先带你把这层窗户纸捅破:底层选型怎么想的、环境怎么搭最快、第一天会踩哪些坑。这篇文章适合三类人看:有 Flutter 基础想往 OpenHarmony 生态扩展的、刚接触鸿蒙开发想找一条跨端捷径的、以及被各种教程绕晕只想把环境跑通然后安心写业务的朋友。
先说结论:Flutter 在 OpenHarmony 上不是“能不能跑”的问题,而是“以什么姿势接入”的问题。官方已经有 sig 仓库在长期维护 Flutter 的 OpenHarmony 适配分支,工具链也在不断完善,编译产物直接打成 hap 包,能装进鸿蒙设备。DAY 1 的核心目标只有一个:把空环境变成一个能创建、能编译、能跑到设备上的 Flutter 工程。整个过程按步骤复现下来大概需要半天,难点不是某个单独环节,而是把 DevEco Studio、OpenHarmony SDK、Flutter 适配分支这三条线对齐。
1. 为什么要在 OpenHarmony 上跑 Flutter:底层选型的核心逻辑
1.1 跨端框架的格局与 Flutter 的独特定位
跨端框架这几年的格局,大致可以分成三类。第一类是 Web 容器方案,典型代表是 Cordova、uni-app 的小程序容器,核心思路是壳子里套 WebView,业务代码还是 Web 那套,好处是前端团队零转型成本,坏处是性能天花板明显,交互复杂的页面会出现肉眼可见的卡顿。第二类是 JavaScript 原生渲染方案,典型代表是 React Native,把 JS 写的组件映射成系统原生控件,性能比 Web 容器好,但桥接层一旦复杂起来,调试和性能优化的成本会直线上升。第三类就是 Flutter 这种自带渲染引擎的方案,Dart 代码直接通过 Skia 渲染到屏幕上,不走系统控件,等于把所有平台都当成“画布”,自己画 UI。
Flutter 到了 OpenHarmony 生态里,优势反而比 Android/iOS 上更突出。因为在 Android 和 iOS 上,Flutter 要跟原生控件体系共存,还得处理各种系统行为差异。而 OpenHarmony 作为一个较新的系统,应用生态还在成长期,Flutter 这种自带渲染引擎的方案可以直接在这块新画布上铺开,不需要跟某套成熟的系统控件体系做深度绑定。换句话说,Flutter 的设计哲学跟 OpenHarmony 的年轻生态非常合拍:我要的是快速覆盖、一致体验、一套代码多端跑。
从上层视角看,选 Flutter 等于选择了一种组合能力:Dart 语言的强类型和 AOT 编译保证性能,自带 Widget 体系保证 UI 一致性,还有庞大的第三方包生态。而这些能力在 OpenHarmony 上不会因为是新平台就打折扣,因为 Flutter 引擎层已经把系统差异给隔离开了。
1.2 选型时要重点盯住的三个维度
性能维度是最先要考虑的。很多人在跨端框架选型时有个误区,觉得“框架选好了性能就有保障了”,实际上框架只能决定性能的上限和下限,真正的性能瓶颈往往在业务层。Flutter 在移动端的性能表现已经有大量案例验证,到了 OpenHarmony 上,虽然引擎还在持续优化,但整体架构决定了它的渲染效率不会差。你要关注的反而是热点路径上有没有额外的桥接开销,比如频繁调用 OpenHarmony 原生的能力时,MethodChannel 的性能损耗是否能接受。
生态维度要看“这个框架在这个平台上有没有人持续维护”。OpenHarmony 的 Flutter 适配不是某个开发者随手做的个人项目,而是放在 openharmony-sig 组织下由社区共同维护的仓库,这一点很重要。有组织背书意味着版本会跟着上游 Flutter 更新、issue 有人响应、坑会有人填。选型时一定要去仓库里看提交频率、issue 处理情况、最近 release 的版本,这些比任何宣传文案都真实。
维护成本维度往往被低估。你要评估的不是“今天能不能跑”,而是“半年后我还能不能升级”。Flutter 上游版本迭代很快,OpenHarmony 的系统版本也在演进,两边都是移动中的靶子。选型时要确认你选择的适配分支是大版本稳定的,以及社区对版本升级的反应速度。我的经验是:宁可选择落后几个小版本的稳定分支,也不要追最新特性分支。环境问题可以解决,版本漂移造成的连锁编译错误真的会让人崩溃。
1.3 先搞清楚你手上的是哪条技术线
准备动手之前,有一件事必须先理清:OpenHarmony 和 HarmonyOS NEXT 是两个不同的东西。OpenHarmony 是开源项目,完全开源,任何人都能下载源码、编译系统、安装到开发板上。HarmonyOS NEXT 是商业发行版,基于 OpenHarmony 开发,但做了商业化的裁剪和增强,主要用于华为的设备。开发 Flutter for OpenHarmony 时,你的目标平台是 OpenHarmony,但很多 Flutter 适配的验证也会跑在 HarmonyOS NEXT 的真机上,这两者的 SDK 和调试工具有一些区别,但核心的 Flutter 适配逻辑是同一套。
具体到仓库层面,OpenHarmony SIG 维护的 flutter_flutter 仓库和上游的 flutter/flutter 仓库是两条线。上游仓库持续演进,SIG 仓库跟着上游同步,但会增加 OpenHarmony 平台相关的代码。用的时候一定要用 SIG 仓库的 OpenHarmony 分支,不能用上游官方仓库直接跑,哪怕能跑到一半也会在原生编译环节报错。这个坑我见不少人踩过:拿官方 Flutter 仓库配了半天环境,最后发现根本找不到 OpenHarmony target。
还有一条容易被忽略的线:ArkUI 和 Flutter 的关系。很多人下意识觉得“鸿蒙开发必须用 ArkUI”,其实 OpenHarmony 的应用开发方式是多样化的,ArkUI 是官方主推的声明式 UI 方案,但 Flutter、React Native 这类跨端框架也有自己的生态位置。选 ArkUI 还是选 Flutter,取决于你的团队背景和产品定位。如果团队已经是 Flutter 栈,要在 OpenHarmony 上快速输出应用,Flutter 适配路线比重新学 ArkUI 要平滑得多。
2. 实战营 DAY 1 开始前的准备:你需要哪些基础
2.1 硬件与系统要求先对齐
开发 Flutter for OpenHarmony,对电脑的要求比普通 Flutter 开发高一些,因为要同时跑 DevEco Studio、OpenHarmony SDK、Flutter 编译链和模拟器。
内存是第一优先级。我自己的开发机是 32GB 内存,跑 DevEco Studio、模拟器和多个终端窗口时正好够用。如果你只有 16GB,跑轻量任务也行,但建议把模拟器换成真机,把编译任务放到命令行单独执行,减少 IDE 常驻内存占用。CPU 方面 Intel i5 或 AMD R5 以上的处理器都能胜任,编译 OpenHarmony 侧代码时多核优势明显。硬盘建议预留至少 60GB 空间,DevEco Studio 本体、SDK 组件、Gradle 缓存、ohpm 缓存加起来不小,C 盘紧张的话建议把 SDK 和缓存目录都改到其他盘。
操作系统方面,Windows 10 以上、macOS 12 以上、Ubuntu 20.04 以上都支持。我主力机是 Windows,整体流程稳定,Mac 上也验证过,基本没有平台差异性的坑。有一点要注意:OpenHarmony 的真机调试在 Windows 上需要安装对应的 USB 驱动,第一次连接设备时系统会提示,按提示装好就行。
设备选择上,入门阶段最省心的是用模拟器。DevEco Studio 自带 Phone 模拟器,启动快、调试方便,跑 Flutter 的 hello world 级别应用完全没问题。如果你手上有 Dayu 开发板这类 OpenHarmony 专用硬件,那更接近真实环境,但调试流程会多一些网络配置和权限处理的步骤。有条件的话,我建议模拟器和真机都试一遍:模拟器用来跑通开发流程,真机用来验证实际性能。
2.2 核心工具链一览:不是只装一个 IDE 就完事
搭建 Flutter for OpenHarmony 环境,涉及的工具链比普通 Flutter 开发多一层,很多新手在第一步就被“为什么要有这么多工具”搞懵了。其实拆开看,各司其职:
DevEco Studio是 OpenHarmony 应用开发的官方 IDE,基于 IntelliJ 平台,专为鸿蒙应用开发设计。它负责的项目管理、代码编辑、签名配置、设备管理和运行调试。Flutter 的 OpenHarmony 适配工程最终要交给 DevEco Studio 来完成原生的构建和部署。
OpenHarmony SDK是开发 OpenHarmony 应用必需的软件开发包,包含 API 接口、工具链、编译资源和模拟器镜像。安装 DevEco Studio 后需要单独下载配置 SDK 版本,也可以直接在 IDE 的 SDK Manager 里管理。SDK 里有一个关键工具叫 ohpm,负责 OpenHarmony 侧的包管理,类似于前端生态里的 npm。
hvigor是 OpenHarmony 的构建引擎,负责把 OpenHarmony 工程编译成 hap 包。它的配置方式类似 Gradle,但使用场景更聚焦。Flutter 工程里的 ohos 目录就是给 hvigor 用的,最终构建时 hvigor 会调用 Flutter 侧的编译产物,整合成可安装的 hap 包。
Node.js必须装。DevEco Studio 的构建工具链和 hvigor 依赖 Node.js 运行时来处理部分自动化流程,没有 Node.js 环境,构建环节会直接报错。安装 LTS 版本即可。
Git用于拉取 Flutter 适配分支。不装 Git 的话,下载压缩包的方式很容易漏文件,而且后续想更新分支也麻烦,强烈建议直接命令行 clone。
Flutter 适配分支,也就是 openharmony-sig/flutter_flutter 仓库,这是整个环境的核心。它不是单独的 SDK,而是 Flutter SDK 的 OpenHarmony 定制版本,放在固定的目录里由 PATH 环境变量引用。
我把这套工具链的关系用一句话总结:Flutter 适配分支负责生成 Dart 侧的构建产物,DevEco Studio 和 hvigor 负责把产物打包成 OpenHarmony 的应用包,ohpm 负责管理 OpenHarmony 侧的第三方依赖,Node.js 是工具链的运行时底座。缺了任何一个环节,后面的流程都会踩断点。
2.3 版本匹配关系速查
搭建环境最怕的不是不会安装,而是版本不匹配。Flutter 的 OpenHarmony 适配分支版本和 OpenHarmony SDK 版本之间有严格的对应关系,乱配的话编译报错会毫无逻辑,排查起来非常痛苦。
我的建议是:装环境的第一天,先确定一个组合,然后把手上的版本都对齐到官方推荐的组合,不要自己混搭。SIG 仓库的 README 里通常会写明当前适配分支对应的 Flutter 版本和 OpenHarmony 版本要求,这是最权威的参考。比如某个分支是基于 Flutter 3.7 做的适配,那你本地 OpenHarmony SDK 最好就用 API 9 或 API 10 的版本,不要上 API 11 的预览版本尝鲜。
版本匹配这件事有个值得分享的经验:不要试图用“最新版”解决问题。Flutter 上游迭代快,OpenHarmony 适配分支往往要滞后一段时间才会覆盖新版本。你如果用 Flutter 3.10 的语法特性去跑一个只适配了 3.7 的分支,代码里用的新 API 在适配分支里压根不存在,编译器给的报错又往往让人误以为是环境问题。所以实战营阶段,老老实实用官方指定的稳定组合,等环境完全跑通了再考虑升级。
版本对齐查起来也不难:打开 flutter_flutter 仓库,看分支名里的版本号,再对照 DevEco Studio 里 SDK Manager 的版本列表,选一个在适配范围内的即可。表格里我给一个参考组合(具体版本以仓库实时信息为准):
| 组件 | 参考版本 | 说明 |
|---|---|---|
| Flutter 适配分支 | oh-3.x-master 系列 | SIG 仓库的 OpenHarmony 分支 |
| OpenHarmony SDK | API 10 或 API 9 | 与适配分支说明保持一致 |
| DevEco Studio | 对应 SDK 版本的配套 IDE | IDE 和 SDK 强关联 |
| Node.js | 16 LTS 或更新 LTS | 作为构建工具链运行时 |
| 构建工具 | hvigor 对应版本 | 随 DevEco Studio 自动配置 |
3. 从零搭建 Flutter for OpenHarmony 环境:完整实操
3.1 安装 DevEco Studio 与 OpenHarmony SDK
第一步是安装 DevEco Studio。去官方网站按系统类型下载对应版本,Windows 版本是 exe 安装包,macOS 是 dmg。安装过程本身没有特别之处,默认配置一路往下走就行,但有一个注意点:存储路径不要用默认的 C 盘 Program Files 这类带空格和权限限制的目录,建议直接建一个 D:\DevEcoStudio 这样的目录,后续可以减少很多权限问题。
第一启动时,DevEco Studio 会引导你安装 OpenHarmony SDK。这一步要重点处理:在 SDK Manager 里选择你要用的 SDK 版本。建议把 SDK、Toolchains、ohpm 都勾上。安装路径同样建议指定到非系统盘,比如 D:\OhosSdk,方便管理和后续的环境变量配置。装完之后它还会自动把 hvigor 相关组件一起装上,这一步别跳过。
现在模拟器也能顺手装一下。DevEco Studio 的 Device Manager 里可以创建 Phone 模拟器和 Tablet 模拟器。首次启动模拟器会下载系统镜像,体积不小,网速慢的话要等一会儿。我建议第一天先把模拟器装好,因为后续验证 Flutter 编译结果的时候,模拟器比找真机更省事。
检查一点:确保 DevEco Studio 能正常启动并创建一个空的原生 OpenHarmony 工程,然后能成功运行到模拟器上。这一步相当于给整个环境打了地基,地基不稳的话,后面 Flutter 的报错很难分清是哪一层的问题。
3.2 拉取 Flutter 的 OpenHarmony 适配分支
接下来是 Flutter 适配分支的获取。命令行执行:
git clone -b oh-3.x-master https://gitee.com/openharmony-sig/flutter_flutter.git这里 -b 参数指定的是分支名,实际分支名以仓库实时信息为准。仓库通常带 oh- 前缀,后面的版本号对应 Flutter 的版本线。建议先把仓库的 branches 页面打开,确认哪个分支是当前活跃的,再执行 clone,避免拉到一个已经停止维护的老分支。
clone 完成后,把该目录命名为一个你容易记住的路径,比如 D:\flutter_ohos,后面所有 Flutter 命令都会从这里走。有两点实操经验分享:
第一,整个开发过程中,这个目录要当作“只读 SDK”对待,不要在仓库里直接改代码。需要改动的地方,全部拿到你自己的项目里去做。原因很直接:它是从上游同步的分支,后续可以用 git pull 更新,一旦你改了源码,更新时就会有冲突,而且你改的东西在仓库升级后会被覆盖,等于白改。
第二,这个仓库的完整体积比较大,clone 可能会慢。如果网络有问题,可以在 gitee 页面上直接下载 ZIP 包,但注意一定要解压到没有中文和空格的路径下,而且以后没法直接用 git pull 更新。能走 git 还是尽量走 git,后续排查问题时可以用 git log 看版本来对照 issue。
3.3 配置环境变量并验证 flutter 命令
拉下来的 Flutter 适配分支要变成真正的命令行工具,核心是把它的 bin 目录加进 PATH 环境变量。Windows 上的操作是:系统属性 -> 环境变量 -> 编辑 Path,把 D:\flutter_ohos\bin 加进去。macOS 或 Linux 则在 .bashrc 或 .zshrc 里加:
export PATH=$PATH:$HOME/flutter_ohos/bin保存后新开一个终端窗口(这一步很关键,老窗口的环境变量不会自动刷新),执行flutter --version就能看到版本信息。如果提示找不到 flutter 命令,基本就是 PATH 没设对或者窗口没重开。
这里有个非常容易被忽略的配置:Device 相关的 SDK 路径。Flutter 的 OpenHarmony 适配分支在识别 OpenHarmony SDK 时,需要知道 SDK 装在哪儿。实践中最稳妥的方式是把 SDK 路径写入一个全局环境变量,命名通常是 DEVECO_SDK_HOME,指向你安装 OpenHarmony SDK 的根目录,比如 D:\OhosSdk。
再介绍一个我习惯用的目录约定:把 Flutter 适配分支、OpenHarmony SDK、Node.js 的主目录全部放到同一个上级目录下,比如 D:\ohos-dev\ 下面,环境变量配置和后续排查都会很直观。
3.4 用 flutter doctor 检查环境是否就绪
环境变量配好之后,执行flutter doctor是标准的自检动作。它会检查 Flutter 环境、Dart 环境、以及当前平台相关的工具链配置情况。
在普通 Flutter 环境里,doctor 会检查 Android 工具链;在 OpenHarmony 适配分支下,它会额外检查 OpenHarmony 侧的工具链配置。第一次跑 doctor 大概率会看到几条红色警告,不要慌,逐个看它缺什么,这里分享几个重点检查项:
Flutter 和 Dart 版本是否匹配,如果不匹配需要执行flutter upgrade或按提示切换到对应版本。OpenHarmony SDK 路径是否能被识别,识别不了就看 DEVECO_SDK_HOME 配得对不对。Node.js 和 ohpm 是否在 PATH 中;另外,Linux 环境下还要注意 udev 规则和 USB 权限的配置,Windows 下则要确认驱动安装。
flutter doctor全部绿了之后,我建议再执行一条命令:
flutter precache --linux它的作用是预下载 Flutter 引擎相关的二进制文件。OpenHarmony 适配也是一样,需要在第一次编译前把引擎相关产物准备好,不然编译时它会临时下载,容易因为网络问题卡住。这个步骤的耗时取决于网速,耐心等它跑完。
3.5 创建并编译第一个 Flutter for OpenHarmony 工程
环境检查就绪后,就可以创建第一个工程了。
flutter create my_first_ohos_app cd my_first_ohos_app这个命令创建的目录和普通 Flutter 工程结构基本一致,包括 lib/ 目录放 Dart 代码、pubspec.yaml 管理依赖。但在 OpenHarmony 适配分支下,它会比普通工程多出一个 ohos 目录,这个目录就是 OpenHarmony 原生工程的壳,hvigor 构建时的入口。
如果用 DevEco Studio 打开这个工程目录,它会自动识别 ohos 子目录并作为 OpenHarmony 应用项目加载。首次加载时,IDE 可能会提示下载或同步 ohpm 依赖,直接点同意即可。
接下来是编译构建。有两种方式:一种是在 DevEco Studio 里直接点运行按钮,另一种是在命令行用 hvigor 构建。实战营阶段我建议用 IDE 操作,因为可视化界面能更直观地看到日志。点击 Run 按钮后,构建过程会做几件事:先由 Flutter 工具链把 Dart 代码编译成 libflutter.so 和相关产物,再由 hvigor 把 ohos 目录下的工程资源整合,最终打成一个 hap 包。第一次构建通常要几分钟,日志里会滚动大量输出。
构建成功后,hvigor 会自动把 hap 包安装到模拟器或连接的真机上,并在设备上拉起应用。看到模拟器里出现一个 Flutter 默认计数器界面,恭喜你,DAY 1 的核心目标已经达成。
这里有一个值得注意的细节:Flutter 默认工程里的计数器 Demo 在 OpenHarmony 上跑起来后,界面上应该能正常点击加号、数字自增。如果这一步没问题,说明 Flutter 引擎在 OpenHarmony 上已经正常工作了,后续你可以放心地开始写业务代码。
4. 第一天最容易踩的坑与排查方法
4.1 环境变量不生效
这是最高频的翻车点。形式表现为:明明已经配置了 PATH,新开终端执行flutter还是提示命令不存在。原因往往有三个:窗口没重开、PATH 配的是用户变量但在管理员窗口里生效不了、把路径配错了层级。
我的排查习惯是先用echo $env:Path(Windows PowerShell)看当前终端实际加载的 PATH 内容,确认没有目标路径。如果没有就重新打开终端;有但执行不到,就看 flutter.bat 脚本所在的路径是否真的存在。macOS/Linux 则用which flutter看实际解析路径,确认不是另一个 Flutter 实例在干扰。
还有一个容易被忽略的点:如果你电脑上之前装过普通 Flutter,那 PATH 里可能存在两个 flutter 入口。环境变量写在前面的会优先被解析,导致你明明配了 OpenHarmony 适配分支,flutter --version却显示普通 Flutter 的版本,进而无法生成 ohos 目录。解决方式是确保 PATH 里 OpenHarmony 适配分支的 bin 目录排在普通 Flutter 前面,或者干脆先临时把普通 Flutter 的路径注释掉。
4.2 DevEco Studio 打开工程后报错 SDK 找不到
这种情况经常发生在 DevEco Studio 的 SDK 路径和 Flutter 侧配置的 DEVECO_SDK_HOME 不一致的时候。IDE 默认用自己配置的 SDK 路径,Flutter 命令行则读环境变量。两边指向不同 SDK 版本时,构建流程就会在中间断掉。
处理方式说起来很简单:在 DevEco Studio 的 SDK Manager 里查看它实际使用的 SDK 路径,然后把环境变量 DEVECO_SDK_HOME 配成同一个路径,重启终端再试。如果你在开发机上装了多个 SDK 版本,务必让 IDE 里选中的版本和环境变量指向的版本保持一致。曾经我在这上面卡了快两小时,就是因为 IDE 里默认用了 API 11,环境变量却指到了 API 10。
4.3 模拟器启动不了或运行后白屏
模拟器启动问题,优先检查虚拟化是否开启。Windows 需要开启 Hyper-V 或 Windows Hypervisor Platform,macOS 要在系统设置里允许虚拟化。如果在 BIOS 层就没开虚拟化,模拟器会直接报错。
白屏问题往往不是 Flutter 层的 bug,而是 hap 包没有正确加载 Flutter 引擎。检查 DevEco Studio 的运行日志,重点看有没有 Flutter 引擎初始化失败的报错。常见原因是 hap 包里的 native 库和设备的 CPU 架构不匹配,比如默认编的是 arm64,但模拟器是 x86_64。解决办法是在 Flutter 工程的构建配置里,确保只构建目标架构对应的产物。
真机上还有一种情况:设备系统版本过低,而 Flutter 适配分支要求的最低 OpenHarmony 版本没达到。碰到这种问题,先看 SIG 仓库的文档,确认支持的系统版本范围。
4.4 编译卡在依赖拉取阶段
构建过程中卡住,最常见的原因是 ohpm 或 Gradle 依赖拉不下来。国内网络环境访问一些远程仓库不稳定,导致构建过程长时间停在 downloading 状态。
解决思路是配置镜像源。ohpm 的全局配置文件里可以把 registry 指向国内镜像,具体地址在 OHOS 官方文档里有公示。配置好之后,清掉原来拉取失败的缓存再重新构建,一般能明显提速。另外,Node.js 的 npm 源也建议在第一天就配成国内镜像,因为 hvigor 构建时可能会调用 npm 下载一些工具链依赖。
这一块我的经验是:不要在构建报错时才去配镜像,你永远不知道哪个环节隐含着网络请求。第一天装环境的间隙就把三个源配好:ohpm、npm、还有 Flutter 的 pub 源。pub 源可以在环境变量里配置 PUB_HOSTED_URL 指向国内镜像。
4.5 第一天最容易忽略的几个小细节
构建时中文路径会引发各种奇怪错误。建议开发机用户名、项目路径、SDK 路径里不要出现中文或空格,尽量用纯英文路径,可以避开一大堆莫名其妙的文件系统兼容问题。
文件实时同步的坑。如果你的项目目录挂载在某些云同步盘中,hvigor 构建时可能会因为文件锁定或同步冲突失败。开发阶段建议关掉项目的云同步功能,构建完成后再手动同步。
日志的阅读能力。第一天养成好习惯:任何报错不要只看结尾几行,往上翻,找到真正的 Error 关键字。构建日志里大量 warning 是正常的,关键是找到第一处 error 出现的位置,那里通常能暴露真正的根因。第一次构建失败时,把现场日志截下来,去 SIG 仓库的 issue 区搜一搜,很多问题已经有解决方案。
我在第一天实操下来最大的体会是:这套环境链的每一个环节都不算复杂,但它们之间是强耦合的,版本一旦不匹配就会产生连锁反应。如果你的环境一直跑不通,优先怀疑版本组合问题,而不是怀疑自己操作有误。把环境变量、SDK 路径、构建配置这三个点逐一梳理清楚,大部分问题都能定位。
明天进入 DAY 2 之前,建议你先做一件事:把 Flutter 适配分支的官方 README 完整读一遍,里面记录了当前分支已知的问题和对应的 workaround,这些信息在后续写业务代码时非常有用。环境搭建只是起点,真正的挑战是理解 Flutter 和 OpenHarmony 在底层如何协作。