HarmonyOS多目标产物构建最佳实践

embedded/2024/10/18 9:21:40/

背景

在Android或iOS开发时经常会有打“马甲”包的场景,就是一套代码打出不同主题的包,一个公司的产品可能针对不同用户提供不同的应用,比如抖音有国内版也有国外版,滴滴有个人版还有企业版,同样的在鸿蒙平台也有类似的诉求,本文我们讨论鸿蒙平台的多产物构建。

HarmonyOS 工程配置文件说明

下面是一个最简单的鸿蒙工程截图:

在这里插入图片描述

工程 build-profile.json5

在一个标准的Android工程中,工程下的模块使用setting.gradle来声明,对应的鸿蒙应用的模块配置在build-profile.json5中:

{  "app": {  "signingConfigs": [],  "products": [  {  "name": "default",  "signingConfig": "default",  "compatibleSdkVersion": "5.0.0(12)",  "runtimeOS": "HarmonyOS",  }  ],  "buildModeSet": [  {  "name": "debug",  },  {  "name": "release"  }  ]  },  "modules": [  {  "name": "entry",  "srcPath": "./entry",  "targets": [  {  "name": "default",  "applyToProducts": [  "default"  ]  }  ]  }  ]  
}

modules列表中声明模块,其中:

  • name:模块名
  • srcPath:模块对应路径
  • targets:构建目标

注意: 这里跟Android有两个不同:

  • 一个工程中只允许有一个entry模块,比如一个SDK工程中想创建两个demo应用模块是不允许的;
  • srcPath路径只能指向工程根目录和子目录,而不能指向不在工程目录下的模块,比如工程A想源码依赖另一个工程B中的模块是不允许的;

模块 build-profile.json5

{  "apiType": "stageMode",  "buildOption": {  },  "buildOptionSet": [  {  "name": "release",  "arkOptions": {  "obfuscation": {  "ruleOptions": {  "enable": true,  "files": [  "./obfuscation-rules.txt"  ]  }  }  }  },  ],  "targets": [  {  "name": "default"  },  {  "name": "ohosTest",  }  ]  
}
  • apiType:API模型类型
    • stageMode:长期演进的模型,官方推荐使用该模型
    • faMode:FA模型
  • buildOptionSet:编译配置集合,主要包含混淆配置规则等。
  • targets:构建目标

module.json5

模块/main/下的module.json5示例:

{  "module": {  "name": "entry",  "type": "entry",  "description": "$string:module_desc",  "mainElement": "EntryAbility",  "deviceTypes": [  "phone",  "tablet",  "2in1"  ],  "deliveryWithInstall": true,  "installationFree": false,  "pages": "$profile:main_pages",  "abilities": [  {  "name": "EntryAbility",  "srcEntry": "./ets/entryability/EntryAbility.ets",  "description": "$string:EntryAbility_desc",  "icon": "$media:layered_image",  "label": "$string:EntryAbility_label",  "startWindowIcon": "$media:startIcon",  "startWindowBackground": "$color:start_window_background",  "exported": true,  "skills": [  {  "entities": [  "entity.system.home"  ],  "actions": [  "action.system.home"  ]  }  ]  }  ],  "extensionAbilities": [  {  "name": "EntryBackupAbility",  "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",  "type": "backup",  "exported": false,  "metadata": [  {  "name": "ohos.extension.backup",  "resource": "$profile:backup_config"  }  ],  }  ]  }  
}

主要作用类似于Android中的AndroidManifest,声明模块信息、deviceTypes等。

  • name:标识当前Module的名称,确保该名称在整个应用中唯一。取值为长度不超过31字节的字符串,不支持中文。应用升级时允许修改该名称,但需要应用适配Module相关数据目录的迁移
  • type:标识当前Module的类型。支持的取值如下:
    • entry:应用的主模块。
    • feature:应用的动态特性模块。
    • har:静态共享包模块。
    • shared:动态共享包模块。
  • srcEntry:标识当前Module所对应的代码路径,取值为长度不超过127字节的字符串。
  • description:标识当前Module的描述信息,取值为长度不超过255字节的字符串,可以采用字符串资源索引格式。
  • deviceTypes:标识当前Module可以运行在哪类设备上。
  • deliveryWithInstall:标识当前Module是否在用户主动安装的时候安装,即该Module对应的HAP是否跟随应用一起安装。
    • true:主动安装时安装。
    • false:主动安装时不安装。
  • requestPermissions:标识当前应用运行时需向系统申请的权限集合。
  • dependencies:标识当前模块运行时依赖的共享库列表。
  • targetModuleName:标识当前包所指定的目标module,确保该名称在整个应用中唯一。取值为长度不超过31字节的字符串,不支持中文。配置该字段的Module具有overlay特性。仅在动态共享包(HSP)中适用。
    更多具体说明参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/module-configuration-file-V5

官方推荐模块结构

由于平级目录进行模块管理有两个缺陷不利于开发及后期维护:

  • 工程逻辑结构混乱
  • 模块间的依赖关系不够清晰

官方推荐common、features、product三层工程结构:

/application├── common                  # 公共特性目录│├── features                # 功能模块目录│   ├── feature1            # 子功能│   ├── feature2            # 子功能2│   └── ...                 # 子功能n│└── product                 # 产品层目录├── wearable            # 智能穿戴泛类目录├── default             # 默认设备泛类目录└── ...

product与target介绍

在介绍多目标产物构建前先介绍下target和product的概念:

  • target:工程内的每一个Entry/Feature模块,对应的构建产物为HAP,HAP是应用/服务可以独立运行在设备中的形态。由于在不同的业务场景中,同一个模块可能需要定制不同的功能或资源,因此引入target的概念。一个模块可以定义多个target,每个target对应一个定制的HAP,通过配置可以实现一个模块构建出不同的HAP。
  • product:一个HarmonyOS工程的构建产物为APP包,APP包用于应用/服务发布上架应用市场。由于不同的业务场景,需要定制不同的应用包,因此引入product概念。一个工程可以定义多个product,每个product对应一个定制化应用包,通过配置可以实现一个工程构建出多个不同的应用包。

最佳实践

目标

要开发一个SDK,这个SDK上面又封装了两个SDK,这两个SDK分别额外实现了ToB和ToC业务的功能,这三个SDK在一个工程中,开发调试时最方便的方式就是可以有三个Demo分别调试这三个不同的SDK。
在这里插入图片描述

方案

由于HarmonyOS工程中只能有一个可运行的entry模块,所以创建三个demo分别运行的方式无法跑通。

"modules": [  {  "name": "app",  "srcPath": "./app",  "targets": [  {  "name": "default",  "applyToProducts": [  "default"  ]  }]  },  {  "name": "app_c",  "srcPath": "./app_c",  "targets": [  {  "name": "default",  "applyToProducts": [  "default"  ]  }  ]  },  {  "name": "app_b",  "srcPath": "./app_b",  "targets": [  {  "name": "default",  "applyToProducts": [  "default"  ]  }  ]  }
]

虽然在build_profile中声明了三个带targets模块,但是只有第一个可以运行。

方案一

可以通过把其他两个配置注释掉,使用运行哪个打开哪个的方式调试,这样的缺点就是每次调试不同模块都需要修改代码。

方案二

Biz2B和Biz2C模块合成一个模块,定义连个target,用不同代码路径区分2B或者2C,但是Biz2B和Biz2C是两个对外独立的SDK,合成一个模块无法对外差异化提供。

方案三

Biz2B和Biz2C模块各自创建两个target,分别是2B和2C,配置源码模块分别制定不同路径,Biz2B模块的2Ctarget指向空路径,这样demo工程虽然依赖了2B模块,但是调试2C的target不会有任何Biz2B的代码。可是使用模块级build_profile.json5中的sourceRoots属性,制定源码路径。

参考文档

  1. https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-customized-multi-targets-and-products-guides-0000001731595144-V5#section2554174114463
  2. https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-using-V5

http://www.ppmy.cn/embedded/90425.html

相关文章

ComfyUI: 报EP Error错误(onnxruntime)

🤶背景描述 在使用反推提示词的时候,按照上一篇介绍的方法是可以正常使用的。 但是看后台的时候,发现有一个错误: *************** EP Error *************** EP Error D:\a\_work\1\s\onnxruntime\python\onnxruntime_pybind_s…

”关于“八股文”对程序员开发作用

在程序员开发的语境中,“八股文”通常指的是那些被广泛讨论、反复练习的技术面试问题和答案,这些问题往往围绕经典的技术知识点,如算法、数据结构、设计模式等。对于“八股文”对程序员开发的作用,可以从以下几个方面进行分析&…

Vulnhub入门篇-Kioptrix2014

1.环境配置 下载地址:https://download.vulnhub.com/kioptrix/kiop2014.tar.bz2 攻击机kali:192.168.26.128(Nat模式) 靶机配置:Nat模式 这里注意,根据官网地址说明,需要我们先将网络适配器…

vue2怎么上传文件夹,并展示文件夹内的图片?

我使用的是element-ui组件库,发现el-upload组件并不能满足需求,于是用原生实现一下,这里贴一下关键代码,如果大家有更好的实现方法,欢迎分享!! 实现效果:

打造专业级电子书,一键导出分享

在这个数字化的时代,电子书作为一种传统的视觉传达方式,依然具有独特的魅力和价值。一本高质量、高颜值的电子书不仅能吸引观众的眼球,还能有效传达信息,提升品牌形象。那么,如何制作出一本高颜值的电子书呢&#xff1…

fastjson-流程分析

参考视频:fasfjson反序列化漏洞1-流程分析 分析版本 fastjson1.2.24 JDK 8u65 分析过程 新建Person类 public class Person {private String name;private int age;public Person() {System.out.println("constructor_0");}public Person(String na…

C++11深度剖析

目录 🚀 前言:C11简介 一: 🔥 统一的列表初始化💫 2.1 {}初始化 二: 🔥 std::initializer_list 💫 2.1 std::initializer_list是什么类型💫 2.2 s…

C语言基础题:迷宫寻路(C语言版)

1.题目描述 机器猫被困在一个矩形迷宫里。 迷宫可以视为一个n x m 矩阵,每个位置要么是空地,要么是墙。机器猫只能从一个空地走到其上、下、左、右的空地。 机器猫初始时位于(1,1)的位置,问能否走到(n,m)位置。 2.输入格式 第一行&#xff0…