news 2026/10/25 23:38:11

Flutter跨平台开发实战:在OpenHarmony上跑通Hello World指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flutter跨平台开发实战:在OpenHarmony上跑通Hello World指南

1. 项目背景与训练营目标拆解

先交代一下这次训练营的背景。开源鸿蒙(OpenHarmony)这几年在技术圈的热度大家有目共睹,尤其是PC版、x86镜像这些词频繁出现在各大社区和下载站,能明显感觉到生态在快速往桌面端和设备端扩散。但真正动手写过鸿蒙应用的人都知道,目前 ArkTS 和 DevEco Studio 这套官方工具链虽然成熟,却有一个天然的门槛——它和安卓、iOS、Web 那套跨平台开发生态是割裂的。你不可能拿一套代码同时跑安卓和鸿蒙,除非走 C++ 或者 Hybrid 方案,但那又牺牲了开发效率。

Flutter 进场之后,情况开始变得不一样了。Flutter 的底层渲染引擎是自绘的,不依赖系统原生控件,这意味着只要鸿蒙侧能提供一个承载 Flutter 引擎的壳子,Dart 代码理论上就能跨端跑。OpenHarmony 从 3.2 版本开始,官方 SIG 社区就在持续推进 Flutter 适配,Flutter 3.7 之后也正式在 openharmony 分支里加入了 hap 构建产物支持。这个“Hello world”看似简单,但它背后实际上是一整套从“安卓思维”切换到“鸿蒙思维”的转折点:工程怎么创建、编译产物怎么变成 hap、怎么安装到模拟器或真机、三方库兼容性怎么处理——每一个环节都可能让新手卡住好几个小时。

我参加的是开源鸿蒙跨平台训练营的第二天,当天的任务就是:用 Flutter 写一个最基础的 Hello world,跑在 OpenHarmony 设备或者模拟器上。听起来像个 trivial 的入门任务,但真做起来,踩坑的密度远超预期。这篇文章就把我当天的完整过程、遇到的所有报错以及排查思路记录下来,给后面入坑的朋友一个参照。适合谁看?准备在 OpenHarmony 上用 Flutter 起步的开发者、被 hap 构建折腾过的新手、以及想了解 Flutter 跨平台方案在鸿蒙上真实落地情况的技术选型人员。

2. 环境搭建与工具链选型

2.1 为什么不能用普通的 Flutter SDK

如果你按 Flutter 官网的步骤装一个标准版 Flutter SDK,然后执行 flutter create,你大概率会发现了一件奇怪的事:项目建好了,flutter run 也能列出设备,但根本没有 OpenHarmony 相关的构建选项。原因很简单——标准 Flutter SDK 不包含 OpenHarmony 平台支持,官方主线只认 Android、iOS、Web、Windows、macOS、Linux 这几个平台。

要让 Flutter 支持鸿蒙,需要到 OpenHarmony SIG 的镜像仓库拉取带 ohos 平台的 Flutter SDK 分支。这个分支是社区维护的,版本节奏会比官方主线慢半拍,但基本能保证 Flutter 的核心功能和 Dart 语法兼容。我当天用的是 flutter 3.7.12-ohos,对应的 Dart 版本是 2.19.6,这个组合在当天的训练营里是经过验证的,稳定性足够。

这里有个容易忽略的点:不要试图在标准版 SDK 上手动添加 ohos 目录,也不要指望 Flutter 官方升级到某个版本后自动支持鸿蒙。这个思路是错的,因为鸿蒙的适配涉及到底层引擎调用链,不是加一个 gradle 配置就能解决的。

2.2 完整工具链清单

当天安装的组件比想象中多,我列一下完整清单:

组件版本/说明关键作用
OpenHarmony SDK3.2 release / API 9提供鸿蒙系统 API 和编译工具链
DevEco Studio4.0 及以上(建议用新版)鸿蒙项目的 IDE,也可以用来管理 SDK
hvigor 构建工具随 DevEco 安装,自动配置负责把鸿蒙工程打包成 hap
Flutter SDK(ohos 分支)3.7.12-ohosFlutter 跨平台开发主工具
hdc 命令行工具位于 OpenHarmony SDK 的 toolchains 目录鸿蒙设备调试与安装工具
Node.js14.19.1 及以上hvigor 编译链路的依赖,需要提前装好

一个常见的错误是只装了 Flutter SDK 和 DevEco Studio,没装 Node.js,结果编译到一半报 hvigor 初始化失败。这个后面会在报错章节展开,这里先提一句:Node.js 是必须的,因为 OpenHarmony 的工程构建脚本依赖 npm 环境。

2.3 环境变量配置的坑

环境变量这块是 Day2 踩得比较深的一个坑。按社区文档的指引,你需要配置三个环境变量:

OHOS_SDK_HOME 指向 OpenHarmony SDK 的根目录 DEVECO_SDK_HOME 指向 DevEco Studio 内置的 SDK 目录 PATH 追加 hdc 和 node 的路径

问题来了——OHOS_SDK_HOME 和 DEVECO_SDK_HOME 指向的目录到底是不是同一个?我在实际操作中测试了多种情况,结论是:如果你直接把 OpenHarmony SDK 加入到 DevEco Studio 管理器中,那么 DevEco 会复制一份 SDK 到它的安装目录下,此时 DEVECO_SDK_HOME 指向的是这份复制的路径,而 OHOS_SDK_HOME 可以指向你自己解压的原始路径。如果你不配置 DEVECO_SDK_HOME,Flutter 的 ohos 工具插件在查找 SDK 时可能会失败,报“Unable to locate OpenHarmony SDK”之类的错误。

这个场景下最简单的做法是:两个变量都配,都指向同一个 SDK 根目录,不会冲突,反而能绕开很多环境查找问题。如果你用的是 DevEco Studio 内置的 SDK,路径一般在:

/devEco-studio/sdk

注意这个目录下还要有 default/openharmony 子目录结构,hvigor 是靠这个层级关系来定位 API 版本的。

2.4 flutter doctor 会告诉你什么

配置完环境变量后,执行 flutter doctor,正常情况下你应该看到多了一个 OpenHarmony 相关的检查项,类似:

[√] OpenHarmony development environment

如果没有出现这一项,大概率是你的 flutter 命令还在用标准版 SDK,或者 ohos 工具插件没有被正确加载。一个快速验证方式是在任意目录执行:

flutter config --list

如果输出里包含 enable-ohos-desktop 或类似选项,说明 ohos 支持已经生效。

另外提一句,我在训练营现场看到不少同学卡在 flutter doctor 检查项里,误以为 Flutter 不支持 OpenHarmony,实际只是 PATH 指向错了 SDK。多阅读一下 flutter doctor 的输出,它已经把诊断信息写到最前面了,不要跳过检查直接开跑。

3. 创建 Hello world 项目的完整实操路径

3.1 用命令创建项目,而不是 IDE 向导

训练营第一天有人直接用 DevEco Studio 新建了一个 Empty Ability 工程,然后在里面尝试手动引入 Flutter 的引擎包,结果发现工程结构完全不同,后面越改越乱。第二天我们统一用 Flutter 命令行创建项目,再把它转换成鸿蒙工程,这个流程更符合“跨平台”的目标——你的业务代码在 Flutter 层,鸿蒙壳只是宿主。

创建命令:

flutter create --platforms=ohos hello_world_app

注意 --platforms=ohos 这个参数,它是 ohos 分支的 Flutter SDK 特有的。如果你忘了加,默认生成的工程只会包含 android、ios 等目录,不会出现 ohos 目录。

执行完成后,项目结构里会多出一个 ohos 目录,这是 Flutter 自动生成的鸿蒙壳工程,里面包含了 entry module、hvigor 配置、以及 Flutter 引擎的依赖声明。如果你用的 SDK 版本和示例一致,还会自动生成一个名为 flutter_ohos_plugin 的本地插件,负责与系统层交互。

3.2 目录结构逐层拆解

生成的工程核心目录大概是这样的:

hello_world_app/ ├── lib/ │ └── main.dart // Dart 层代码入口 ├── ohos/ │ ├── entry/ │ │ ├── src/main/ │ │ │ ├── ets/ // 鸿蒙的 Ability 和页面入口 │ │ │ ├── resources/ // 应用图标、字符串等资源 │ │ │ └── module.json5 // 模块配置 │ │ └── build-profile.json5 // 构建配置 │ └── build-profile.json5 ├── pubspec.yaml └── analysis_options.yaml

这里最关键的三个文件是:

  1. ohos/entry/src/main/module.json5:声明了应用的入口 Ability、权限和窗口配置。
  2. ohos/build-profile.json5:定义了整个工程的编译参数、签名信息和 SDK 版本。
  3. ohos/entry/build-profile.json5:模块级别的构建参数,其中 externalNativeOptions 里会有 CMake 和 libflutter.so 的链接配置。

如果你的工程要往真机上跑,还需要在ohos/entry/src/main/resources/base/profile/下配置main_pods.json——不对,这个文件名是 iOS 的,鸿蒙的是module.json5里的pages字段,指向pages/Index.ets。

当然,这些文件在 Hello world 阶段一般不需要手动改,但你知道它们的作用之后,遇到编译错误就不会一脸蒙了。尤其是 build-profile 里如果 SDK 版本配得和本机不一致,编译时会直接报 API 版本不匹配。

3.3 修改 Hello world 文本

按照训练营要求,我们把 main.dart 里的默认计数器改成最简单的文本输出:

import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('OpenHarmony + Flutter')), body: const Center( child: Text('Hello World from Flutter on OpenHarmony!'), ), ), ); } }

这段代码在任何 Flutter 平台都通用,不需要因为目标设备是鸿蒙就改 Dart 层。这也是跨平台框架最大的好处:业务代码写一次,剩下的事情交给脏活累活的壳工程去做。

修改完代码后,如果是在 IDE 里开发,建议先执行flutter analyze检查语法错误,再执行构建命令。训练营现场有人直接点运行,报了一堆 Dart 语法错误,才发现改错了文件——编辑器里打开的是test/widget_test.dart而不是lib/main.dart。这个低级错误真的很多人犯。

3.4 拉取依赖和插件

执行完 create 和代码修改后,需要同步一下依赖:

flutter pub get

这一步会生成 .dart_tool 目录下的 package_config.json,同时会在 ohos 目录下生成一些自动生成的配置文件。如果 pub get 报错,先把网络代理关掉或切到国内可用镜像,因为 pub.dev 在国内的访问不是一直稳定的。训练营里用的是清华镜像:

PUB_HOSTED_URL=https://pub.flutter-io.cn FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

配置方式是在系统环境变量中新建这两个,然后重新打开终端。注意这个步骤要在 flutter pub get 之前做,否则缓存里的包索引还是指向国外的地址。

同步完依赖后,在 ohos 目录下会新增.ohos相关缓存和oh-package-lock.json5文件,是正常的。

4. 运行到鸿蒙模拟器与真机的完整流程

4.1 准备一台鸿蒙设备或模拟器

如果你有 OpenHarmony 的真机(比如润和、DAYU 系列开发板),用 USB 连接电脑即可。如果是纯模拟器,需要在 DevEco Studio 里创建一个 Phone 模拟器镜像。训练营当天大部分同学用的是本地模拟器,原因是手头没有开发板,用模拟器可以跑通验证链路,后续比赛再上真机。

模拟器的启动方式:打开 DevEco Studio,进入 Device Manager,点击 Device 标签下的模拟器镜像,下载一个 API 9 的 Phone 镜像,启动它。整个过程需要比较长的下载时间,所以给人感觉“卡住”了也正常。

设备就绪后,命令行里执行:

hdc list targets

如果能看到设备的 serial 号,说明 hdc 连接正常。一个常见的现象是 hdc 已经启动了,但 list 结果为空——这通常是因为 DevEco Studio 内部的 hdc 和命令行 hdc 版本不一致,两端服务握手失败。解法是杀掉所有 hdc 进程,重新启动,或者直接用 DevEco Studio 内置的 hdc:

cd /path/to/sdk/toolchains ./hdc kill ./hdc start ./hdc list targets

4.2 构建 hap 包的关键命令

在工程根目录下,执行:

flutter build hap --debug

这里要解释一下,flutter build hap 是 ohos 分支的 Flutter SDK 新增的构建命令,它的作用相当于 Flutter 里的 flutter build apk,但产物是 hap 格式。构建过程分两个阶段:第一阶段编译 Dart 代码为 libapp.so,第二阶段调用 hvigor 将 libapp.so 和 Flutter 引擎的 libflutter.so 打包进 hap。

执行完之后,输出路径是:

build/outputs/hap/ohos/debug/

目录下会有 entry-debug-signed.hap 和 entry-debug-unsigned.hap 两个文件。如果只看到 unsigned 没有 signed,说明签名环节出了问题,无法直接安装,需要先看 4.3 的签名配置。

4.3 自动签名和手动签名的区别

Hello world 这个阶段,通常用 DevEco Studio 的自动签名就已经足够了。前提是你得先在 DevEco Studio 里登录华为账号,然后在 File > Project Structure > Signing Configs 中勾选 Automatically generate signature。DevEco 会自动生成 .cer 和 .p12 文件,并且把签名信息同步到 build-profile.json5 中。

如果不用 DevEco Studio,纯命令行构建的话,签名配置比较麻烦,需要自己调用 hapsigntool 命令行工具生成签名。不建议第一天就折腾这个,直接打开 DevEco Studio 做一次自动签名,然后再回命令行构建。

注意:自动签名生成的密钥是调试用的,不能用于发布上架。但对于 Hello world 和训练营项目,已经够用。

4.4 安装并启动应用

先用 hdc 检查连接状态,然后安装签名后的 hap:

hdc install build/outputs/hap/ohos/debug/entry-debug-signed.hap

如果安装顺利,终端会返回 install success。此时到模拟器的应用列表里,应该能看到一个以 Flutter 项目名命名的应用图标,点击就能运行。但命令行方式可以直接启动:

hdc shell aa start -a EntryAbility -b com.example.hello_world_app

这里 -b 参数后面的包名需要和 module.json5 里的 bundleName 保持一致,一般在创建项目时就已经自动配置好了。启动成功的话,模拟器屏幕上会显示 Flutter 的 UI 界面和 Hello world 文本。

如果启动失败,比较常见的是日志里出现Ability not found或Bundle not found,这种情况通常是安装的 hap 和启动命令中的 bundleName 不一致,或者安装的是 unsigned 包——unsigned 包不会出现在应用列表里,但 aa start 还是会尝试启动。

5. 运行过程中的典型报错与排查实录

5.1 Gradle 插件声明方式报错

这是热词列表里出现频率最高的一条:

You are applying Flutter's main Gradle plugin imperatively using the apply

翻译一下:你在使用 apply 语句命令式地应用 Flutter 主 Gradle 插件。这个报错一般出现在 Android 工程的 build.gradle 里,但在 ohos 项目的某些混合场景下也会冒出来,尤其是工程从标准 Flutter 项目迁移到 ohos 分支,或者 IDE 自动生成了重复的 Gradle 配置时。

产生原因:Flutter 新版 Gradle 插件要求使用 plugins DSL 声明式方式引入,而不是老的 apply 方式。旧的做法是在 build.gradle 里写:

apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

新做法是:

plugins { id "dev.flutter.flutter-gradle-plugin" }

解决方案:打开 android 目录下的 build.gradle(虽然我们在做 ohos,但这个检查项是 Android 侧残留的),把 apply 方式换成 plugins DSL。如果 android 目录不是你当前关注的重点,也可以直接删除 android 目录,只保留 ohos。

提示:学习过程中如果暂时不需要 Android 平台,建议删掉 android 目录,可以少很多干扰项。跨平台项目在初期阶段聚焦单一目标平台更高效。

5.2 Dart VM 初始化器报错

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled exception:

这是 Flutter 引擎层的报错,发生在 Dart VM 初始化阶段,通常意味着 Dart 层在启动时抛出了未捕获异常。Hello world 项目出现这个报错,十有八九是 main.dart 里引用了不存在的包或插件,或者 pubspec.yaml 里声明的依赖和实际代码不一致。

我的排查步骤:

  1. 先看完整堆栈,报错信息下面会跟一串 Dart 代码调用链,指明具体是哪一行代码异常。
  2. 回到 main.dart,逐个注释可疑代码块,重新 build hap,再安装运行。
  3. 如果确认是依赖问题,执行flutter pub get --offline检查本地缓存,或删除 .dart_tool 目录重新拉取。

这个报错还有一个常见原因——通过热加载运行代码时,Dart 虚拟机重新加载了一个有状态残留的快照,导致初始化异常。建议先冷启动一次完整构建流程,避免热更新过程中出现奇怪的中间态。

5.3 新建项目后跑不起来的排查顺序

我经常收到同学的私信,说 Flutter 新建项目后跑不起来,报错五花八门。汇总起来无非几类:

现象可能原因解决方向
flutter run 找不到设备模拟器未启动或 hdc 版本不一致重启 hdc,确认 hdc list targets 有输出
构建报 No such file or directoryohos 目录缺失或 SDK 路径错误检查 OHOS_SDK_HOME 是否指向正确位置
安装时报 INSTALL_PARSE_FAILEDhap 包签名无效或设备不兼容重新自动签名,确认 API 版本匹配
运行时报 libflutter.so not foundhap 内未打入 Flutter 引擎检查 externalNativeOptions 配置
页面白屏Ability 加载的 ets 页面未绑定 Flutter 容器检查 Index.ets 中 Flutter 容器初始化代码

排查顺序建议:先确认环境(flutter doctor 和 hdc),再确认构建过程(重点看 hvigor 的输出日志),最后确认安装和启动(hdc install 与 aa start 的日志)。不要一上来就怀疑是 Flutter 或鸿蒙的兼容性问题,80% 的环境问题在 Day2 阶段都会暴露在第一条链路里。

5.4 hvigor 编译速度极慢的优化

训练营当天,好几个同学在第一次构建 hap 时发现编译特别慢,几分钟过去进度条还在 30% 左右。慢的原因通常是第一次构建需要下载 hvigor 依赖和编译 native 代码。这里有三个能立刻看到效果的优化:

  • 使用 config 的镜像:把 hvigor 仓库地址指到国内镜像,通过ohpm config set registry配置。
  • 关闭不必要的校验:Debug 模式下可以暂时把checkRelease关掉,减少代码校验时间。
  • 给 Node.js 足够的内存:在 hvigor 构建命令前设置NODE_OPTIONS=--max-old-space-size=4096,避免 GC 频繁触发导致构建抖动。

之后再次构建会快很多,因为增量编译只处理改动的部分。如果你第二次构建还是同样的慢,看看是否误触发了 clean 操作,那会强制全量编译。

5.5 Flutter 组件通信与 Provider 的实战笔记

Day2 虽然主要讲 Hello world,但训练营的群里已经有人开始追问组件通信和状态管理了。刚好热词列表里出现了 “flutter组件通信”、“flutter provider 怎么用” 这两个词,我就一起记录一下,方便后面用到。

Flutter 里组件通信主要分三类:父传子、子传父、跨组件。Hello world 阶段用不到,但了解基础语义有助于后续项目的快速推进:

  • 父传子:构造参数直接传值,最简单直接。
  • 子传父:通过回调函数(Callback)实现。
  • 跨组件:使用 InheritedWidget 或第三方状态管理库,比如 Provider。

Provider 是目前社区使用率很高的状态管理方案。它本质上是对 InheritedWidget 的封装,通过 ChangeNotifier 来管理状态变化。一个最简用法:

class CounterModel extends ChangeNotifier { int _count = 0; int get count => _count; void increment() { _count++; notifyListeners(); } } void main() { runApp( ChangeNotifierProvider( create: (_) => CounterModel(), child: const MyApp(), ), ); } // 在组件里读取 final counter = context.watch<CounterModel>();

需要注意,Provider 是纯 Dart 层的东西,不依赖任何平台 API,因此在 OpenHarmony 的 Flutter 工程中同样可以正常使用。这意味着如果你后续的鸿蒙应用需要复杂状态管理,完全可以把 Android/iOS 上那套 Provider 经验直接搬过来。

5.6 Impeller 渲染引擎在鸿蒙上的情况

热词里出现了 flutter impeller。Impeller 是 Flutter 官方的新渲染引擎,目标是替换 Skia。但在 OpenHarmony 的 ohos 分支上,Impeller 目前还不可用,构建时会自动回退到 Skia。原因是 Impeller 的 GPU 后端已经支持 Vulkan 和 Metal,但 OpenHarmony 的图形栈和这两个后端有一些兼容性差异,社区还没有完成适配。

所以如果你在自己的鸿蒙 Flutter 应用里遇到了渲染异常,比如文字模糊、图像闪烁,先不要怀疑 Impeller,而是检查自己的 shader 或图片资源是否和 ArkTS 原生渲染有冲突。之前有个同学在鸿蒙模拟器上加载一个带模糊滤镜的图片,发现边缘锯齿很重,一度以为是 Impeller 的问题,后来换了高分辨率图片资源就好了。模拟器本身对图形资源的处理也有一定损耗,这不是 Flutter 特有的。

6. 真机模拟器常见差异与图形兼容性

6.1 模拟器能confirm,真机不一定能过

训练营的最后一个环节是真机测试。部分同学的代码在模拟器上正常显示,一放到真机上就开始出问题。最常见的是 OpenHarmony 3.2 版本的模拟器和 4.0 真机之间的 API 差异。模拟器镜像的 API 是固定的,真机则可能已经升级到你电脑上 SDK 不支持的版本。

一个明显的差异是窗口尺寸和 Density 的适配。模拟器默认分辨率是 1080x2340,真机可能是 720p 或 2K 屏。Flutter 的 UI 是逻辑像素驱动的,大部分情况下都能自适应,但如果你用了MediaQuery.of(context).size做绝对定位,就可能在某些机型上出现边缘被裁切或留白过多。

解决方案很简单——All things being equal,用布局约束来替代绝对坐标,尽量使用 Center、Align、Expanded 和 Flex 布局。Hello world 场景看不出来,但如果你继续做 Flutter + 鸿蒙应用,这个点早晚会遇到。

6.2 OpenHarmony 桌面版的交叉验证

热词里反复出现“开源鸿蒙pc版官网下载”“开源鸿蒙x86iso下载”这类词,说明不少人已经在关注 PC 版。OpenHarmony 的桌面版支持 x86 架构,也提供了 ISO 镜像。但如果你想直接在 PC 上跑 Flutter 应用,要注意两个问题:一是桌面版目前默认使用 ArkUI 渲染,Flutter 的 ohos 分支对这种形态支持还比较基础;二是 x86 模拟器上 hdc 连接方式和 ARM 设备不一样,可能要走网络化连接而不是 USB。

如果你手上没有开发板但想在 PC 环境快速体验,我的建议是优先用 QEMU 挂载 ISO 镜像,开启本地虚拟化。底层运行 OK 之后,再用 devtool 检查 Flutter 引擎是否加载成功。注意,这个过程需要一定的 Linux 使用基础,不适合连模拟器都还没点亮就跑。 Day2 训练营的任务只需要在模拟器上跑通即可,桌面版后续环节再做也不迟。

6.3 ArkTS 和 Flutter,怎么选

热词里还有一条很有意思:“arkts和flutter谁更流行”。这个问题的答案其实取决于你站在哪个视角:

  • 如果目标是做 OpenHarmony 原生应用,ArkTS 是无法绕过的。官方文档、组件库、IDE 工具链全部优先支持 ArkTS,生态位置稳的一批。
  • 如果目标是同时覆盖安卓、iOS、Web、桌面、鸿蒙多个平台,Flutter 的跨平台能力更有价值。一套 Dart 代码,多端复用,维护成本显著降低。

在训练营的架构里,ArkTS 负责鸿蒙壳工程里的原生能力,Flutter 负责业务层的跨平台 UI。两者不是对立关系,而是协作关系。后面进阶内容会涉及到如何在 ArkTS 侧调用 Flutter 的方法,或者在 Flutter 侧通过 MethodChannel 调用鸿蒙的系统 API,那才是这个方案真正发力的地方。

7. 实操经验总结与后续扩展方向

写完整个 Day2 的完整记录,最后说一点个人感受。

我在实际跑通这个 Hello world 之前,一直以为 Flutter 在 OpenHarmony 上的最大难点是构建工具链或者编译速度。真正上手之后才发现,最大的成本在于“思维切换”——你把标准 Flutter 的那一套环境认知带过来,处处碰壁;只有理解了 ohos 目录是个独立的鸿蒙壳工程,Flutter 只是嵌在里面的一个组件,很多问题就能想通了。

对于训练营后面的内容方向,我可以先透露一个小技巧:Hello world 跑通之后,不要着急写业务代码,先把 libapp.so、libflutter.so 和 hap 包的关系研究明白,理解一次构建产物里哪些东西是引擎的、哪些是你的业务代码、哪些是鸿蒙壳的配置,这对后面排查真机问题和性能优化会非常有帮助。

再分享一个我个人的习恨建议:在开发 Flutter + OpenHarmony 应用时,尽量保持一个小而美的代码量,比如一个页面只显示一个列表,或者一个简单的表单。不要一上来就把复杂业务全部导入,因为 Flutter 在 OpenHarmony 上的 debug 热重载体验比 Android 要弱一些,经常会有状态残留、渲染丢失的现象。小而美的页面可以更快定位问题是出在 Flutter 层还是鸿蒙层。

最后,如果你这篇文章看到这里,大概率你已经成功在自己的电脑上跑通了 Flutter 的鸿蒙 Hello world。如果还没跑通,也不要气馁,按步骤再走一遍,遇到报错就按第 5 章的排查表对号入座。跨平台开发本身就是反复和环境作斗争的过程,跑通第一个 hap 之后,后面的路会顺很多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/25 23:05:32

应急响应实战复盘:从畸形图片Webshell到内存取证揪出后门

这届帕鲁杯出现了好几个值得反复琢磨的应急响应赛题&#xff0c;我印象最深的是那道《畸形的爱》&#xff0c;出题方是知攻善防实验室。光看名字觉得像剧情杀&#xff0c;真正进题之后才发现&#xff0c;这是一道典型的蓝队视角应急响应题&#xff0c;考的是日志分析、恶意文件…

作者头像 李华
网站建设 2026/10/19 3:14:23

MySQL数据类型选择实战:从手机号、金额到索引失效的避坑指南

聊到 MySQL 数据类型&#xff0c;许多开发的第一反应是&#xff1a;int、varchar、datetime&#xff0c;选一个就完事。我过去也这么想&#xff0c;直到被线上事故教训过几次。这篇文章主要聊 MySQL 数据类型怎么选才能少踩坑&#xff1a;数值、字符串、日期时间、JSON 四大类型…

作者头像 李华
网站建设 2026/10/19 3:14:23

服务器攻击与防御实战指南:从DDoS到WebShell的排查与加固

干服务器运维这行越久&#xff0c;越明白一件事&#xff1a;你永远不知道下一分钟攻击会从哪个方向来。我接手过一台被挖矿脚本占满CPU的Web服务器&#xff0c;半夜替电商客户处理过CC攻击打到带宽爆掉的告警&#xff0c;也亲眼见过同事因为一条文件上传漏洞&#xff0c;整个后…

作者头像 李华
网站建设 2026/10/19 5:19:10

RADIUS协议原理与Wi-Fi企业认证实战指南

简介&#xff1a;本资源是一份面向网络工程初学者与高校教学场景的RADIUS协议系统性教案&#xff0c;聚焦用户认证、授权与计费&#xff08;AAA&#xff09;核心机制&#xff0c;解决企业网接入控制、教育网按流量计费、VOD点播计时等典型应用场景中的身份验证难题。教案以Word…

作者头像 李华
网站建设 2026/10/19 5:19:12

Agent-Reach 实战:用 CLI 为 AI Agent 接上执行的手

1. 从"Agent-Reach"这个名字说起&#xff1a;它到底想解决什么问题 第一次看到 Agent-Reach 这个项目名&#xff0c;我的直觉是&#xff1a;这大概率是一个围绕 AI Agent 能力边界做文章的工具&#xff0c;而不是又一个"套壳聊天框"。原因很简单——"…

作者头像 李华