在HarmonyOS应用开发中,开发者需要实现渠道打包功能,即在编译构建时根据不同的渠道配置生成对应的应用安装包。部分应用在迁移到HarmonyOS前可能依赖原有的渠道打包库(如Walle Library SDK),在HarmonyOS侧需要相应的替代方案来实现运行时读取渠道号或编译时生成多渠道包的能力。
HarmonyOS提供了定制多目标构建产物的能力,允许开发者在编译时通过不同的配置生成多个APP或HAP。通过定义不同的target和product,可以在构建时同时打包生成不同的安装包,甚至为不同的APP指定不同的页面入口。更多参考请参见定制多目标构建产物和配置多目标产物-能力说明。
Walle Library SDK的核心能力是在运行时从APK中读取渠道号,无需在代码中硬编码。在HarmonyOS中,可通过构建产物定制配合运行时读取BuildProfile或metadata的方式实现等效能力。
在HarmonyOS中,可以通过定制多目标构建产物来实现渠道打包功能,具体步骤如下:
在工程根目录的build-profile.json5中,通过targets和products字段定义多渠道构建配置。每个target对应一个渠道,通过runtimeOS、name等字段区分;product用于定义产物维度的差异。示例配置如下:
{
"app": {
"signingConfigs": [],
"products": [
{
"name": "default",
"signingConfig": "default",
"compatibleSdkVersion": "5.0.0(12)",
"runtimeOS": "HarmonyOS"
}
],
"targets": [
{
"name": "default",
"runtimeOS": "HarmonyOS"
},
{
"name": "huawei",
"runtimeOS": "HarmonyOS",
"applyToProducts": ["default"]
},
{
"name": "myapp",
"runtimeOS": "HarmonyOS",
"applyToProducts": ["default"]
}
]
}
} 上述配置定义了default、huawei、myapp三个target,分别对应不同渠道。构建时DevEco Studio会根据选中的target生成对应的HAP/APP产物。
通过在module层级的build-profile.json5中为不同target配置source字段,可以实现不同渠道使用不同的源码集、资源文件或页面入口。示例配置如下:
{
"module": {
"name": "entry",
"type": "entry",
"deviceTypes": ["default", "tablet"],
"targets": [
{
"name": "default",
"source": {
"pages": {
"$value": "src/main/ets/pages/default_pages"
},
"resources": {
"$value": "src/main/resources/default_resources"
}
}
},
{
"name": "huawei",
"source": {
"pages": {
"$value": "src/main/ets/pages/huawei_pages"
},
"resources": {
"$value": "src/main/resources/huawei_resources"
}
}
}
]
}
} 通过上述配置,huawei渠道会使用huawei_pages目录下的页面和huawei_resources目录下的资源,实现渠道差异化。更多详情参见定义产物的source源码集-pages。
HarmonyOS构建系统会在编译时生成BuildProfile类,其中包含当前构建产物的targetName和productName信息。开发者可在运行时通过BuildProfile获取当前渠道标识,替代Walle Library SDK的运行时读取能力。示例代码如下:
import { BuildProfile } from 'BuildProfile';
@Entry
@Component
struct Index {
@State channelName: string = '';
aboutToAppear(): void {
// 运行时读取当前构建产物的targetName作为渠道号
this.channelName = BuildProfile.targetName;
console.info('当前渠道号:' + this.channelName);
}
build() {
Column() {
Text('当前渠道: ' + this.channelName)
.fontSize(24)
.margin({ top: 50 })
}
.width('100%')
.height('100%')
}
} 另外,如果需要在module.json5中通过metadata方式传递渠道信息,可在target配置中通过metadata字段注入自定义渠道参数,运行时通过@ohos.bundle.bundleManager读取module的metadata信息。示例代码如下:
import { bundleManager } from '@kit.AbilityKit';
// 读取modulemetadata中的渠道信息
async function getChannelFromMetadata(): Promise<string> {
const bundleInfo = await bundleManager.getBundleInfoForSelf(
bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_METADATA
);
// 遍历metadata查找渠道标识
for (const module of bundleInfo.hapModuleInfos) {
if (module.moduleName === 'entry' && module.metadata) {
const channelMeta = module.metadata.find(
(item: Record<string, string>) => item.name === 'channel'
);
if (channelMeta) {
return channelMeta.value;
}
}
}
return 'unknown';
} 在DevEco Studio中,可通过Build菜单选择不同的target进行构建。使用命令行构建时,可通过hvigorw命令指定target和product,示例命令如下:
# 构建指定target的HAP产物 hvigorw assembleHap --mode module -p product=default --target huawei # 构建指定target的APP产物 hvigorw assembleApp --mode project -p product=default --target huawei
为便于区分不同渠道的产物,建议在build-profile.json5中通过output字段自定义产物命名规则,或在CI/CD流水线中对产物重命名,格式建议为{appName}-{channel}-{version}-{buildTime}.hap,便于后续分发和统计。