鸿蒙+Flutter混合工程化:构建、依赖管理与持续集成实战

前言:从"玩具"到"工业"的跨越

在前几期文章中,我们探讨了鸿蒙与Flutter混合开发的架构、UI和通信细节。但在真实的商业项目中,**"怎么写代码"只是成功的一半,"怎么构建、怎么管理依赖、怎么自动化发布"**往往决定了项目的生死。

鸿蒙生态拥有独特的构建工具链(Hvigor、Ohpm),而Flutter也有自己的构建体系。当两者结合时,如何处理依赖冲突 、如何实现自动化构建 、以及如何进行多环境配置,成为了摆在开发者面前的新难题。

本文将深入混合开发的工程化细节,带你打通从代码提交到应用上架的"最后一公里"。


一、 项目结构设计:Flutter与鸿蒙的"物理"融合

在混合开发中,项目结构的设计直接决定了后续维护的难度。

1.1 两种主流模式对比
模式 结构描述 适用场景 优缺点
Flutter主控模式 Flutter项目为主,鸿蒙作为platforms/ohos存在 新项目,以Flutter为主 优点 :Dart生态管理方便。 缺点:鸿蒙原生能力接入较深时,配置繁琐。
鸿蒙主控模式 鸿蒙项目为主,Flutter作为Module或C++库嵌入 大型存量鸿蒙项目改造 优点 :符合鸿蒙工程规范,原生交互方便。 缺点:Flutter热重载体验可能受影响。

推荐方案 :对于大多数中大型项目,推荐使用**"鸿蒙主控 + Flutter Module"**的方式,通过 flutter build aarhar 包的形式将Flutter产物嵌入鸿蒙工程,实现物理隔离。

1.2 目录结构最佳实践
bash 复制代码
my_harmony_flutter_app/
├── entry/                  # 鸿蒙主模块
│   ├── src/
│   └── module.json5
├── flutter_module/         # 独立的Flutter模块
│   ├── lib/
│   ├── pubspec.yaml
│   └── android/ohos/...    # 平台特定配置
├── oh_modules/             # 鸿蒙三方库 (Ohpm)
├── build-profile.json5     # 构建配置
└── hvigorw                 # Hvigor构建脚本

二、 依赖管理:三方库的"大一统"

在混合项目中,我们面临着两套依赖体系:Dart的pub和鸿蒙的ohpm

2.1 Dart依赖管理(pubspec.yaml)
  • 镜像源 :必须配置华为镜像源,否则在CI/CD服务器上可能拉取失败。

    yaml 复制代码
    environment:
      sdk: ">=2.19.0 <4.0.0"
    
    # 配置华为镜像源
    publish_to: https://pub.flutter-io.cn
2.2 鸿蒙原生依赖(Ohpm)

很多Flutter插件底层依赖了鸿蒙的原生SDK(如地图、推送)。

  • 操作 :在 oh-package.json5 中声明依赖。

    json 复制代码
    {
      "dependencies": {
        "com.huawei.hms:map": "6.0.0"
      }
    }
  • 冲突解决 :当Flutter插件自带的原生库版本与鸿蒙主工程引入的版本不一致时,需要在构建脚本中进行版本仲裁(Version Resolution Strategy)。


三、 构建流程深度定制(Hvigor)

鸿蒙的构建工具 Hvigor 是基于Gradle改造的,我们可以通过配置 hvigorfile.jsbuild-profile.json5 来定制混合构建流程。

3.1 自动化构建脚本

为了让CI/CD服务器能自动构建混合项目,我们需要编写脚本来自动触发Flutter构建。

javascript 复制代码
// hvigorfile.js (部分逻辑示意)
const { execSync } = require('child_process');

// 在编译鸿蒙HAP之前,先构建Flutter
function buildFlutterModule() {
  console.log('正在构建Flutter模块...');
  try {
    // 进入Flutter目录,构建产物输出到鸿蒙模块的libs目录
    execSync('cd flutter_module && flutter build hap --build-output=../entry/libs/flutter_output', { stdio: 'inherit' });
  } catch (error) {
    console.error('Flutter构建失败', error);
    process.exit(1);
  }
}

// 注册Hvigor任务钩子
module.exports = {
  hooks: {
    beforeBuild: buildFlutterModule
  }
}
3.2 多环境配置(Flavor)

鸿蒙支持 product 配置,Flutter支持 --dart-define,我们需要将两者结合。

  • 配置文件build-profile.json5

    json 复制代码
    {
      "products": [
        {
          "name": "dev",
          "signingConfig": "default",
          "compatibleSdkVersion": "5.0.0(12)",
          "flutterDefine": "ENV=dev&API_URL=https://api.dev.com"
        },
        {
          "name": "prod",
          "signingConfig": "release",
          "flutterDefine": "ENV=prod&API_URL=https://api.prod.com"
        }
      ]
    }
  • 构建命令

    bash 复制代码
    # 构建开发版
    hvigor assembleHap -p product=dev
    
    # 构建生产版
    hvigor assembleHap -p product=prod

四、 持续集成与持续部署(CI/CD)

在企业开发中,手动构建是不可接受的。我们需要搭建自动化流水线。

4.1 环境准备

在Jenkins/GitLab Runner服务器上,需要预装:

  1. JDK 17
  2. Node.js (用于Ohpm)
  3. Flutter SDK (鸿蒙定制版)
  4. DevEco CLI (用于命令行构建鸿蒙应用)
4.2 流水线脚本(Pipeline)
groovy 复制代码
pipeline {
    agent any
    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }
        stage('Setup Flutter') {
            steps {
                sh '''
                    export PUB_HOSTED_URL=https://pub.flutter-io.cn
                    export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
                    flutter --version
                '''
            }
        }
        stage('Flutter Pub Get') {
            steps {
                sh 'cd flutter_module && flutter pub get'
            }
        }
        stage('Build HarmonyOS App') {
            steps {
                sh 'hvigor assembleHap -p product=prod --mode module --publish'
            }
        }
        stage('Archive') {
            steps {
                archiveArtifacts artifacts: 'build/default/outputs/default/*.hap', fingerprint: true
            }
        }
    }
}

五、 签名与发布:最后一道关卡

鸿蒙应用的签名机制与Android不同,混合应用需要特别注意。

  1. 自动签名 vs 手动签名
    • 开发阶段使用自动签名(autoSign)。
    • 发布阶段必须使用**发布证书(.p12)Profile文件(.p7b)**进行手动签名。
  2. 多HAP签名
    • 如果你的应用拆分了多个HAP(如按功能模块拆分),确保所有HAP使用同一个签名,否则在安装时会因为签名不一致而失败。
  3. 上架审核

六、 总结

鸿蒙与Flutter的混合开发,不仅仅是技术的堆叠,更是工程能力的考验

通过合理的项目结构划分 、严谨的依赖管理 、以及自动化的CI/CD流水线,我们可以将混合开发的复杂性降到最低,让团队能够专注于业务逻辑的实现,而不是陷入构建脚本的泥潭。

互动话题

你们的团队在鸿蒙+Flutter的混合构建中,是采用AAR嵌入方式,还是纯源码方式?遇到了哪些构建性能上的瓶颈?欢迎在评论区交流经验!

点赞 ▲ 收藏 ⭐ 评论 💬 转发 ➡️

欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

相关推荐
TrisighT3 小时前
ArkTS 列表滚动时为什么会闪现旧数据?我扒了 LazyForEach 的复用逻辑
harmonyos·arkts·arkui
MonkeyKing3 小时前
鸿蒙ArkTS深度剖析:ArkTS与TS/JS核心差异、静态强类型实战优势
typescript·harmonyos
TrisighT3 小时前
Electron鸿蒙PC上写日志文件,我被权限和路径坑了两次
electron·harmonyos
你听得到115 小时前
用户说 App 卡,但说不清在哪?我把 Flutter 监控 SDK 升级成了链路观测工作台
前端·flutter·性能优化
TrisighT1 天前
一个下午搞定 ArkTS 折叠面板?结果我从两点写到晚上九点
harmonyos·arkts·arkui
stringwu2 天前
Flutter 开发必备:MVI 架构的高效实现指南
前端·flutter
程序员老刘3 天前
Flutter版本选择指南:3.44系列继续观望 | 2026年6月
flutter·ai编程·客户端
花椒技术4 天前
HJPusher / HJPlayer SDK 实践:我们为什么把直播推播链路拆成一套可复用能力
设计模式·harmonyos·直播
用户965597361904 天前
Provider vs Bloc vs GetX vs Riverpod:Flutter 状态管理方案怎么选?
flutter
一维Ace4 天前
HarmonyOS ArkTS 按钮组件全解:Button、Toggle 状态交互实战
harmonyos