当前位置: 首页 > article >正文

鸿蒙-hvigor定制构建

文章目录

    • 前言
    • BuildProfile
      • 实践
    • 替换模块module.json5字段的值
      • 实践
    • 打包签名

前言

之前需要发版时都是在开发机上修改一下相关配置,比如签名文件、三方SDK参数等,然后打包上传到应用商店。略显繁琐,也担心某次打包会有漏改错改的配置。现在使用jenkins搭建了构建流水线,希望可以根据传入的参数不同,替换配置文件中的字段。翻看文档后发现可以在hvigorfile.ts中接收部分编译配置。

BuildProfile

该类和 Android 项目中的 BuildConfig类很像,也是在编译构建时生成的。我们可以通过该类在运行时获取编译构建参数,也可以在build-profile.json5中通过buildProfileFields增加自定义字段,从而在运行时获取自定义的参数。

实践

项目代码已经迭代了将近10年,有些功能的添加没有办法做到完美向下兼容,只能在请求参数中添加当前应用版本号,服务端根据版本号来判断需要下发哪些数据。但鸿蒙版本是刚开发开发,在一个版本内无法完成全部功能,需要分版本按紧急程度开发,因此版本号也不能直接和 Android、iOS 对齐,也是从 1.0.0 版本开始发版。所以无法在请求参数中直接传递应用版本号。因此我们将当前适配的版本号写入到BuildProfile.ets文件中,方便各个业务调用。

我们在项目根目录下的build-profile.json5文件中添加如下内容就可以将自定义的字段写入到该文件中.

{
	app: {
		products: [{
			name: "default",
			signingConfig: "default",
			compatibleSdkVersion: "5.0.0(12)",
			runtimeOS: "HarmonyOS",
			buildOption: {
				arkOptions: {
					buildProfileFields: {
						online: false,
						version_to_servier: "5.11.10",
					},
				}
			},
		},
		]
	}
}

自定义参数可以在buildOptionbuildOptionSettargets节点下的arkOptions子节点中通过增加buildProfileFields字段实现,自定义参数通过key-value键值对的方式配置,其中value取值仅支持numberstringboolean类型。
当然,该配置也可以在模块下的build-profile.json5中配置。优先级如下:

模块级target > 模块级buildOptionSet > 模块级buildOption > 工程级product > 工程级buildModeSet

这里我们添加了version_to_servier字段来表示当前应用适配到了哪个版本。
正常情况下,我们运行代码就可以在${moduleName} / build / ${productName} / generated / profile / ${targetName} 目录下生成BuildProfile.ets文件。
也可以在命令行执行hvigorw GenerateBuildProfile
也可以选中需要编译的模块,在菜单栏选择Build > Generate Build Profile ${moduleName}
也可以在菜单栏选择Build > Build Hap(s)/APP(s) > Build Hap(s)”或“Build > Build Hap(s)/APP(s) > Build APP(s)

使用时可以这么用

import BuildProfile from './BuildProfile';
const VERSION_TO_SERVER: string = BuildProfile.version_to_servier;

替换模块module.json5字段的值

我们使用了某三方SDK,需要在模块module.json5文件中添加对应的id

{
  "module": {
    "metadata": [
      {
        "name": "xxx_APPID",
        "value": "1234567"
      }
    ],
  }
}

为了区分测试环境和生产环境,xxx_APPID配置了不一样的值,我们期望是打包时通过命令行参数来修改这个值,避免认为配置出现错误。

实践

使用命令行hvigorw打包时除了buildModedebuggable等参数外,还支持--config properties.key=value进行自定义参数。并且在模块下、工程下的hvigorfile.ts中都可以接收到该参数。

这里我们定义了布尔类型的online参数来表示是否为发版包,当模块下的hvigorfile.ts文件中根据该字段的值来区分配置的参数。
具体代码如下,在模块下的hvigorfile.ts文件中:

import { hapTasks, OhosHapContext, OhosPluginId } from '@ohos/hvigor-ohos-plugin';
import { getNode } from '@ohos/hvigor'

const entryNode = getNode(__filename);
// 为此节点添加一个afterNodeEvaluate hook 在hook中修改module.json5的内容并使能
entryNode.afterNodeEvaluate(node => {
  //获取命令行参数
  let online = false
  let propertyOnline = hvigor.getParameter().getProperty('online');
  if (propertyOnline != undefined) {
    online = propertyOnline
  }
  console.log("entry online-> " + propertyOnline);

  // 获取此节点使用插件的上下文对象 此时为hap插件 获取hap插件上下文对象
  const hapContext = node.getContext(OhosPluginId.OHOS_HAP_PLUGIN) as OhosHapContext;
  // 通过上下文对象获取从module.json5文件中读出来的obj对象
  const moduleJsonOpt = hapContext.getModuleJsonOpt();
  // 修改obj对象为想要的,此处举例修改module中的deviceTypes
  let metaDateList = moduleJsonOpt['module']['metadata']
  metaDateList.forEach(element => {
    if (element['name'] === 'xxx_APPID') {
      if (online) {
        console.log('线上环境,修改xxx_APPID配置为   abcdefg')
        element['value'] = 'abcdefg'
      }else{
        console.log('测试环境,修改xxx_APPID配置为   1234567')
        element['value'] = '1234567'
      }
    }
  });

    // 将obj对象设置回上下文对象以使能到构建的过程与结果中
    hapContext.setModuleJsonOpt(moduleJsonOpt);
})
export default {
    system: hapTasks,  /* Built-in plugin of Hvigor. It cannot be modified. */
    plugins:[]         /* Custom plugin to extend the functionality of Hvigor. */
}

在打包构建时只需要执行

  hvigorw clean  assembleApp -p buildMode=release --config properties.online=true

就可以直接替换为生产环境的配置了。因为平时开发都是直接点 IDE 中的 run 进行调试,不会传入该参数,也就不会影响文件中原本配置的值。

打包签名

上面也提到自定义的参数也可以在工程下的hvigorfile.ts接收到该参数,上面BuildProfile中也提到在工程下的build-profile.json5添加了自定义字段online。我们同样可以根据命令行参数替换掉。同时也将配置的测试签名文件删除,只构建产物,随后再使用命令行进行签名。

代码如下,在工程根目录下的hvigorfile.ts文件中

import { appTasks, OhosAppContext, OhosPluginId } from '@ohos/hvigor-ohos-plugin';
import { hvigor,getNode } from '@ohos/hvigor'
// 获取根节点
const rootNode = getNode(__filename);
// 为根节点添加一个afterNodeEvaluate hook 在hook中修改根目录下的build-profile.json5的内容并使能
rootNode.afterNodeEvaluate(node => {

    //获取命令行参数
    let online = false
    let propertyOnline = hvigor.getParameter().getProperty('online');
    if (propertyOnline != undefined) {
        online = propertyOnline
    }
    console.log("online-> " + propertyOnline);

    // 获取app插件的上下文对象
    const appContext = node.getContext(OhosPluginId.OHOS_APP_PLUGIN) as OhosAppContext;
    // 通过上下文对象获取从根目录build-profile.json5文件中读出来的obj对象
    const buildProfileOpt = appContext.getBuildProfileOpt();
    //将 BuildProfile 文件中的online值改为传入的值
    buildProfileOpt['app']['products'][0]['buildOption']['arkOptions']['buildProfileFields']['online'] = online
    if (online) {
      //清除签名文件信息
        buildProfileOpt['app']['signingConfigs'] = []
    }
    
    // 将obj对象设置回上下文对象以使能到构建的过程与结果中
    appContext.setBuildProfileOpt(buildProfileOpt);
})

export default {
    system: appTasks,  /* Built-in plugin of Hvigor. It cannot be modified. */
    plugins:[]         /* Custom plugin to extend the functionality of Hvigor. */
}

打包的时候,由于上架需要 app 文件,所以我们需要打 release 模式的 app 文件。测试时需要打release 模式的hap 文件:

//先安装一下依赖
ohpm install --all
//发版包
hvigorw clean  assembleApp -p buildMode=release --config properties.online=true 
//测试包
hvigorw clean  assembleHap -p buildMode=release --config properties.online=false

这样我们就将BuildProfile文件中的online值改为传入的值,同时也清除了签名文件配置。

这里需要注意的是,如果执行的是assembleApp,则产物是在项目根目录build/outputs/${productName}/xxx-default-unsigned.app。如果执行的是assembleHap,则会在${moduleName}/build/${productName}/outputs/${productName}/entry-default-unsigned.hap.

下面我们对产物进行签名。

 /Applications/DevEco-Studio.app/Contents/jbr/Contents/Home/bin/java -jar /Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/lib/hap-sign-tool.jar sign-app -keyAlias "keyAlias" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "release.cer" -profileFile "release.p7b" -inFile "build/outputs/default/xxx-default-unsigned.app" -keystoreFile "default.p12" -outFile "xxx-default-signed.app" -keyPwd "keyPwd" -keystorePwd "keystorePwd" -signCode "1"

 /Applications/DevEco-Studio.app/Contents/jbr/Contents/Home/bin/java -jar /Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/lib/hap-sign-tool.jar sign-app -keyAlias "keyAlias" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "debug.cer" -profileFile "debug.p7b" -inFile "entry/build/default/outputs/default/entry-default-unsigned.hap" -keystoreFile "default.p12" -outFile "entry-default-signed.hap" -keyPwd "keyPwd" -keystorePwd "keystorePwd" -signCode "1"

我们可以把打包签名的流程写在文件(build.sh)中,每次去执行这个文件就好了



# 初始化build_type为release
online=true
# 解析命令行参数
while [[ $# -gt 0 ]]; do
    case $1 in
        --debug)
            online=false
            echo "需要构建测试包"
            shift
            ;;
        --release)
            # 实际上这个选项是多余的,因为默认就是release
            # 但如果你希望明确指定release以覆盖其他可能设置默认值的逻辑,可以保留
            online=true
            echo "需要构建线上包"
            shift
            ;;
        *)
            # 未知选项,打印帮助信息或错误消息
            echo "Usage: $0 [--debug|--release]"
            exit 1
            ;;
    esac
done



# 安装依赖
ohpm install --all


if [ "$online" == true ]; then
    # 打线上 app 包
    echo "Executing online release build commands..."
    hvigorw clean  assembleApp -p buildMode=release --config properties.online=true 
elif [ "$online" == false ]; then
    # 打测试 hap 包
    echo "Executing not online release build commands..."
    hvigorw clean  assembleHap -p buildMode=release --config properties.online=false
else
    # 理论上不应该走到这里,除非build_type被设置为非预期的值
    echo "Unknown build type: $build_type"
    exit 1
fi



# 签名

if [ "$online" == true ]; then
    # 打线上 app 包
    echo "签名 app 文件"
    /Applications/DevEco-Studio.app/Contents/jbr/Contents/Home/bin/java -jar /Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/lib/hap-sign-tool.jar sign-app -keyAlias "keyAlias" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "release.cer" -profileFile "release.p7b" -inFile "build/outputs/default/xxx-default-unsigned.app" -keystoreFile "default.p12" -outFile "xxx-default-signed.app" -keyPwd "keyPwd" -keystorePwd "keystorePwd" -signCode "1"

elif [ "$online" == false ]; then
    # 打测试 hap 包
    echo "签名 hap 文件"
    /Applications/DevEco-Studio.app/Contents/jbr/Contents/Home/bin/java -jar /Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/lib/hap-sign-tool.jar sign-app -keyAlias "keyAlias" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "debug.cer" -profileFile "debug.p7b" -inFile "entry/build/default/outputs/default/entry-default-unsigned.hap" -keystoreFile "default.p12" -outFile "entry-default-signed.hap" -keyPwd "keyPwd" -keystorePwd "keystorePwd" -signCode "1"

else
    # 理论上不应该走到这里,除非build_type被设置为非预期的值
    echo "Unknown build type: $build_type"
    exit 1
fi

打包时,如果需要打测试包,则执行 build.sh --debug,如果要打发版包,则执行build.sh --release


http://www.kler.cn/a/554765.html

相关文章:

  • 【数据挖掘】深度挖掘
  • 前后端分离的Netty + WebSocket实现聊天室
  • 【JAVA:list中再定义一个list对象,循环赋值不同的list数据,出现追加重复数据问题】
  • Android13-包安装器PackageInstaller-之apk安装流程
  • AI IDE 使用体验及 AI 感受
  • Paimon(数据湖框架)概述
  • 金属色渐变在UI设计中怎么用?
  • Mac下Python版本管理,适用于pyenv不起作用的情况
  • 数据结构中的邻接表
  • 常见的软件测试模型及特点
  • MongoDB数据导出工具mongoexport
  • 菜鸟之路Day17一一IO流(三)
  • Linux系统编程之高级信号处理
  • 文字识别软件cnocr学习笔记
  • VisionMaster4.4 python脚本 图像处理 转换函数 爱之初体验
  • 七星棋牌顶级运营产品全开源修复版源码教程:6端支持,200+子游戏玩法,完整搭建指南(含代码解析)
  • 功能开关聚合对象实践:提升金融领域的高可用性
  • 最新 :服务器的cuda版本太老旧怎么办--cuda安装指南
  • 钉钉多维表:数据管理与协作的新篇章
  • WEB安全--SQL注入--bypass技巧