鸿蒙应用开发-初见:Hvigor

前言

本篇文章仅会介绍API9之后的Hvigor构建工具及其插件hvigor-ohos-plugin。且仅会介绍stage模型下的配置

  1. 鸿蒙使用Hvigor工具链对应用或服务进行打包,打包后的产物位于各自模块下的build文件夹中
  2. 打包后的产物包括一个.app文件和多个.hap文件
  • .hap是可以直接运行在模拟器或真机设备中的软件包
  • .app则是用于应用/服务上架到华为应用市场
  1. 任务流的执行是通过构建插件hvigor-ohos-plugin利用Hvigor的任务编排机制实现的

修改构建工具和构建插件版本

修改 hvigor 目录下的 hvigor-config.json5 文件

json 复制代码
{
  "@ohos/hvigor": "1.6.0",
  "dependencies": {
        "@ohos/hvigor-ohos-plugin": "1.6.0"
  }
}

工程目录、配置文件、配置构建信息

无论是工程(App)级还是模块(Module)级,都提供以下三个文件

  1. 构建配置文件(build-profile.json5)
  2. 构建脚本文件(hvigorfile.ts)
  3. 依赖配置文件(oh-package.json5)

构建配置文件 build-profile.json5🌟🌟🌟

构建配置文件,配置构建过程的一些参数

工程级 build-profile.json5

json 复制代码
{
  "app": { 
    //工程的签名信息,可包含多个签名信息
    "signingConfigs": [  
      {
        "name": "default",  //标识签名方案的名称
        "type": "HarmonyOS",  //标识HarmonyOS应用
        //该方案的签名材料
        "material": {  
          "certpath": "D:\\SigningConfig\\debug_hos.cer",  //调试或发布证书文件,格式为.cer
          "storePassword": "******",  //密钥库密码,以密文形式呈现
          "keyAlias": "debugKey",  //密钥别名信息
          "keyPassword": "******",  //密钥密码,以密文形式呈现
          "profile": "D:\\SigningConfig\\debug_hos.p7b",  //调试或发布证书Profile文件,格式为.p7b
          "signAlg": "SHA256withECDSA",  //密钥库signAlg参数
          "storeFile": "D:\\SigningConfig\\debug_hos.p12"  //密钥库文件,格式为.p12
        }
      }
    ],
    "compileSdkVersion": 9,  //指定HarmonyOS应用/服务编译时的SDK版本
    "compatibleSdkVersion": 9,  //指定HarmonyOS应用/服务兼容的最低SDK版本
    //定义构建的产品品类,如通用默认版、付费版、免费版等
    "products": [  
      {
        "name": "default",  //定义产品的名称,支持定制多product目标产物,具体请参考定制多目标构建产物
        "signingConfig": "default",  //指定当前产品品类对应的签名信息,签名信息需要在signingConfigs中进行定义
      }
    ]
  },
  "modules": [
    {
      "name": "entry",  //模块名称
      "srcPath": "./entry",  //标明模块根目录相对工程根目录的相对路径
      "targets": [  //定义构建的APP产物,由product和各模块定义的targets共同定义
        {
          "name": "default",  //target名称,由各个模块的build-profile.json5中的targets字段定义
          "applyToProducts": [  
            "default"   //表示将该模块下的"default" Target打包到"default" Product中
          ]
        }
      ]
    }
  ]
}

模块级 build-profile.json5

json 复制代码
{
  "apiType": 'stageMode',  //API类型,支持FA和Stage模型
  "showInServiceCenter": true,  //是否在服务中心展示
  "buildOption": {
    //配置筛选har依赖.so资源文件的过滤规则
    "napiLibFilterOption": {
      //按照.so文件的优先级顺序,打包最高优先级的.so文件
      "pickFirsts": [
        "**/1.so"
      ],
      //按照.so文件的优先级顺序,打包最低优先级的.so 文件
      "pickLasts": [
        "**/2.so"
      ],
      //排除的.so文件
      "excludes": [
        "**/3.so"
      ],
      //允许当.so重名冲突时,使用高优先级的.so文件覆盖低优先级的.so文件
      "enableOverride": true
    },
    //cpp相关编译配置
    "externalNativeOptions": {
      "path": "./src/main/cpp/CMakeLists.txt",  //CMake配置文件,提供CMake构建脚本
      "arguments": "",  //传递给CMake的可选编译参数
      "abiFilters": [  //用于设置本机的ABI编译环境
        "armeabi-v7a",
        "arm64-v8a"
      ],
      "cppFlags": ""  //设置C++编译器的可选参数
    },
  },
  "targets": [  //定义的Target,开发者可以定制不同的Target,具体请参考定制多目标构建产物
    {
      "name": "default",
      "runtimeOS": "HarmonyOS",
    },
    {
      "name": "ohosTest",
    }    
  ]
}

依赖配置文件 oh-package.json5🌟🌟🌟

应用/服务支持通过ohpm来安装、共享、分发代码,管理项目的依赖关系。oh-package.json5格式遵循标准的ohpm规范

工程级 oh-package.json5

json 复制代码
{
  "name": "myapplication",
  "version": "1.0.0",
  "description": "Please describe the basic information.",
  "main": "",
  "author": "",
  "license": "",
  "dependencies": {},
  "devDependencies": {
    "@ohos/hypium": "1.0.6"
  }
}

模块级 oh-package.json5

json 复制代码
{
  "name": "entry",
  "version": "1.0.0",
  "description": "Please describe the basic information.",
  "main": "index.ets",
  "author": "",
  "license": "",
  "dependencies": {},
}

oh-package.json5中配置ohpm包依赖🌟🌟🌟

ohpm原生三方包

json 复制代码
"dependencies": {
  // 包名:语义化版本
  "eslint": "^7.32.0",
  ... 
}

ohpm三方共享包

json 复制代码
"dependencies": {
 "@ohos/lottie": "^2.0.0",
 ...
}

ohpm本地共享模块

json 复制代码
"dependencies": {
 "library": "file:../library", 
 ...
}

依赖安装和同步

两种方式

  1. 在Terminal窗口执行ohpm install命令下载依赖包
  2. 单击编辑器窗口上方的 Sync Now 进行同步

依赖包会存储在工程或各模块的oh_modules目录

怎么启动构建

  1. 通过单击按钮,DevEco Studio会启动应用/服务的编译,并将编译后的HAP部署到设备中
  2. 通过DevEco Studio的 Build 菜单栏的编译选项进行构建,HAP的构建结果存放于各模块的"build"文件夹下,APP包的构建结果存放于工程的"build"文件夹下

默认开启模块化编译模式

  1. 应用模块化编译是指 基于ESModule的Bundleless编译模式 ,使用原生ES Module规则构建源码。
  2. Stage工程默认开启模块化编译,可有效缩短增量编译时间、减小编译后的包体积

开启AOT编译模式

AOT(Ahead Of Time)即提前编译,能够 在Host端(即运行DevEco Studio的电脑)将字节码提前编译成Target端(即运行应用的设备)可运行的机器码 ,这样字节码可以获得充分编译优化,放到Target端运行时可以获得加速

AOT编译模式

在模块级build-profile.json5文件中,buildOption内的aotCompileMode字段可以设置为以下值,对应不同的AOT模式。

取值 不同的AOT编译模式
type 默认模式,仅编译类型信息到字节码文件,编译速度最快。
partial 使用记录高频操作信息的ap文件(Arkcompiler Profile)进行部分编译,编译速度较快。

使用type编译模式

json 复制代码
{
  "apiType": 'stageMode',
  "buildOption": {
    "aotCompileMode": "type"
  },
  ...
}

使用partial编译模式

  1. 使用partial编译模式需要先使用type模式进行编译,获取到ap文件后,再进行partial模式编译
  2. 这种编译方式类似于Xcode的PGO文件,需要在相应场景下先运行一段时间,然后把ap文件从设备里取出来使用。一般使用较少,大家要了解的话点标题进入自己去看就行,挺简单的

DevEco编译Release版本的HAP🌟🌟

  1. 点击菜单栏 Run -> Edit Configurations 或者 Run App的下拉箭头
  1. 点击左上角 ➕ 或者 Command + N,在弹出的列表中选择 Hvigor
  2. Name中填写名称,Application parameters配置以下参数

--mode module -p product=default assembleHap -p debuggable=false

  1. 在构建App的下拉列表中选择BuildRelease后,点击右边的启动编译

HAP唯一性校验逻辑

  1. HAP是应用安装的基本单位 ,在DevEco Studio工程目录中,一个HAP对应一个Module。应用打包时,每个Module生成一个.hap文件
  2. 应用如果包含多个Module,在应用市场上架时,会将多个.hap文件打包成一个.app文件(称为Bundle),但在云端分发和端侧安装时,仍然是以HAP为基本单位
  3. 为了能够正常分发和安装应用,需要保证一个应用安装到设备时,Module的名称、Ability的名称不重复,并且只有一个Entry类型的Module与目标设备相对应

Module校验逻辑

校验目的:同一目标设备上Module唯一

  1. 校验Module的Name:如果多个Module的Name不同,则校验通过。如果Name相同,继续校验deviceType。
  2. 校验设备类型deviceType。如果deviceType不相交,则校验通过。如果deviceType相交,继续校验distroFilter
  • deviceType不相交是指两个Module的deviceType中配置了完全不同的设备
json 复制代码
//Module1和Module2配置了完全不同的设备,deviceType不相交。
//Module1
{
    "deviceType": ["TV", "tablet"]
}
//Module2
{
    "deviceType": ["car", "router"]
}
  • deviceType相交是指两个Module的deviceType中包含了相同的设备
json 复制代码
//Module1和Module2因为都包含"tablet"设备,导致deviceType相交。
//Module1
{
    "deviceType": ["TV", "tablet"]
}
//Module2
{
    "deviceType": ["car", "tablet"]
}
  1. 校验分发规则distroFilter。目前仅在API8的工程中校验。后面我们都会使用API9甚至10的版本,如果这块规则继续保留,咱们再回来看

Ability校验逻辑

校验目的:同一目标设备上Ability唯一

  1. 校验Ability的Name。如果多个Ability的Name不同,则校验通过。如果Name相同,继续校验Ability所属Module的deviceType。
  2. 校验Ability所属Module的deviceType。如果deviceType不相交,校验通过。如果deviceType相交,继续校验Ability所属Module的distroFilter
  • 两个Ability的Name相同,但其所属Module的deviceType不相交,校验通过
json 复制代码
//Ability1和Ability2虽然名称相同,但由于其所属Module的deviceType不相交,所以可以区分两个Ability,校验通过。
//Ability1
{
    "module": {
        "name": "module_sample1",
        "deviceType": ["TV", "tablet"],
        "abilities": [
    {
        "name": "ability_sample"
    }
        ]
    }
}
//Ability2
{
     "module": {
        "name": "module_sample2",
        "deviceType": ["car", "router"],
        "abilities": [
    {
        "name": "ability_sample"
    }
        ]
    }
}
  1. 校验Ability所属Module的distroFilter。目前仅在API8的工程中校验。后面我们都会使用API9甚至10的版本,如果这块规则继续保留,咱们再回来看

Entry校验逻辑

校验目的:目标设备只有一个Entry类型的Module与之对应,Feature类型的Module经过deviceType及distroFilter指明的目标设备都需要存在Entry类型的Module

  1. 校验Feature类型的Module经过deviceType及distroFilter指明的目标设备都存在Entry类型的Module

例如,Bundle中存在一个Entry类型Module1,其支持设备为tablet和wearable,其分发规则为circle和rect形状的屏幕,同时存在一个Feature类型的Module2,通过分发规则可知,其可以分发到rect形状的tablet和wearable设备上,而rect形状的tablet和wearable设备上存在Entry类型的Module1,校验通过

json 复制代码
//Entry类型Module1
{
    "module": {
        "name": "module_sample1",
        "type": "entry",
        "deviceType": ["tablet", "wearable"],
        "metadata": [
            {
                "name": "distroFilter_config",
                "resource": "$profile:distroFilter_config1"
            }
        ]
    }
}
//Module1的distroFilter,distroFilter_config1.json
{
    "screenShape":{
        "policy": "include",
        "value": ["circle", "rect"]
    }
}
//Feature类型Module2
{
     "module": {
        "name": "module_sample2",
        "type": "feature",
        "deviceType": ["tablet", "wearable"],
         "metadata": [
            {
                "name": "distroFilter_config",
                "resource": "$profile:distroFilter_config2"
            }
        ]
    }
}
//Module2的distroFilter,distroFilter_config2.json
{
    "screenShape":{
        "policy": "include",
        "value": ["rect"]
    }
}
  1. 校验目标设备只有一个Entry类型的Module与之对应

a. 校验Entry类型Module的deviceType。如果deviceType不相交,校验通过。如果deviceType相交,继续校验Entry类型Module的distroFilter

例如,同一个Bundle中存在两个Entry类型的Module,分别为Module1和Module2,两者的deviceType不相交,可以有效区分两个Module,校验通过。

json 复制代码
//Entry类型Module1
{
    "module": {
        "name": "module_sample1",
        "type": "entry",
        "deviceType": ["tablet"]
    }
}
//Entry类型Module2
{
     "module": {
        name: "module_sample2",
        "type": "entry",
        "deviceType": ["wearable"]
    }
}

b. 校验Entry类型Module的distroFilter。如果distroFilter不相交,校验通过。如果distroFilter相交,校验失败,打包失败

同样的,这个等API10出来后看一下是否还支持,再做解析

构建混淆的闭源HAR🌟🌟

  1. 新建一个Module,选择静态库模板

2. 进行开发代码,目录结构存储参照如下

tree 复制代码
  library  // HAR根目录
  ├─libs  // 存放用户自定义引用的Native库,一般为.so文件
  └─src
  │   └─main
  │     ├─cpp
  │     │  ├─types  // 定义Native API对外暴露的接口  
  │     │  │  └─liblibrary  
  │     │  │      ├─index.d.ts
  │     │  │      └─oh-package.json5 
  │     │  ├─CMakeLists.txt  // CMake配置文件  
  │     │  └─hello.cpp  // C++源码文件
  │     └─ets  // ArkTS源码目录
  │     │  └─components
  │     │     └─mainpage
  │     │         └─MainPage.ets
  │     ├─resources  // 资源目录,用于存放资源文件,如图片、多媒体、字符串等  
  │     └─module.json5  // 模块配置文件,包含当前HAR的配置信息  
  ├─build-profile.json5  // Hvigor编译构建所需的配置文件,包含编译选项
  ├─hvigorfile.ts  // Hvigor构建脚本文件,包含构建当前模块的插件、自定义任务等
  ├─index.ets  // HAR的入口文件,一般作为出口定义HAR对外提供的函数、组件等   
  └─oh-package.json5  // HAR的描述文件,定义HAR的基本信息、依赖项等
  1. 定义导出文件入口

在oh-package.json5中 "main" 字段定义导出文件入口。若不设置"main"字段,默认以当前目录下index.ets为入口文件,依据.ets>.ts>.js的顺序依次检索

json 复制代码
{
  "name": "myhar",
  "version": "1.0.0",
  "description": "Please describe the basic information.",
  "main": "index.ets",
  "author": "",
  "license": "Apache-2.0",
  "dependencies": {}
}

以将ets/components/mainpage/MainPage.ets文件设置为入口文件为例

json 复制代码
{
  ...
  "main": "./src/main/ets/components/mainpage/MainPage.ets",
  ...
}
  1. 在当前HAR模块的build-profile.json5中,将artifactType字段值设置为obfuscation
json 复制代码
{
  // 只有stageMode才支持代码混淆
  "apiType": "stageMode",
  "buildOption": {
    // 进行代码混淆
    'artifactType': "obfuscation"
  },
  "targets": [
    {
      "name": "default",
      "runtimeOS": "HarmonyOS"
    }
  ]
}
  1. 若部分工程源文件无需构建到HAR包中,可在module目录下新建 .ohpmignore 文件,用于配置打包时要忽略的文件,支持正则表达式写法。将无需打包进HAR包的文件/文件夹名称写入 .ohpmignore 文件中。DevEco Studio构建时将过滤掉 .ohpmignore文件中所包含的文件目录

6. 选中HAR模块的根目录,点击 Build > Make Module '<module-name>'启动构建。

构建完成后,build目录下生成闭源HAR包产物

如需将闭源包转换为开源包,请将模块级build-profile.json5中"artifactType"字段值改为"original"或直接删除(缺省为original),再次触发编译

json 复制代码
{
  "apiType": 'stageMode',
  "buildOption": {
    "artifactType": "original", // original表示不使用混淆模式
    ...
  },
  ...
}

一次构建多个产物🌟🌟🌟🌟🌟

多工程构建配置

多工程开发能力支持将大型应用拆分为多个模块,每个模块对应一个单独工程

在每个工程分别编译生成HAP后,需统一打包生成一个APP,用于上架应用市场

  1. 分别在每个工程的build-profile.json5配置文件中,设置multiProjects字段值为true
json 复制代码
{
  "app": {
    ...
    "multiProjects": true,
  }
}
  1. 使用如下命令,将多个HAP进行打包
  • hap-list:多个HAP文件名称,如"1.hap"和"2.hap",用逗号隔开;
  • out-path:生成的APP名称,如"final.app"
css 复制代码
java -jar app_packing_tool.jar --mode multiApp --hap-list 1.hap,2.hap --out-path final.app

单工程构建不同的目标产物

product概念

  1. 一个HarmonyOS工程由一个或多个模块组成,工程的构建产物为APP包,APP包用于应用/服务发布上架应用市场
  2. 一个工程可以定义多个product,每个product对应一个定制化应用包,通过配置可以实现一个工程构建出多个不同的应用包

target概念

  1. 工程内的每一个Entry/Feature模块,对应的构建产物为HAP,HAP是应用/服务可以独立运行在设备中的形态。
  2. 一个模块可以定义多个target,每个target对应一个定制的HAP,通过配置可以实现一个模块构建出不同的HAP

定制HAP多target构建产物

  1. 每一个Entry/Feature模块均支持定制不同的target,通过模块中的build-profile.json5文件实现差异化定制
  2. 当前支持 设备类型(deviceType)、源码集(source)、资源(resource)、C++依赖的.so(buildOption) 的定制

定义多target产物的targets

  1. 每一个target对应一个定制的HAP,在定制HAP多目标构建产物前,应提前规划好需要定制的target名称。可以通过targets字段完成
  2. Har模块只有默认配置的default Target,不支持定制其它Target
  1. 在定义HarmonyOS应用/服务的target时,需要通过runtimeOS字段标识该Target是一个可运行在HarmonyOS设备上的HAP
  2. 如果未定义该字段,或该字段取值为OpenHarmony,则表示该Target是一个运行在OpenHarmony设备上的HAP,不能运行在HarmonyOS设备上

下面文件定义了default、free和pay 3个target,在编译构建时,会同时打出三个包

json 复制代码
{
  "apiType": 'stageMode',
  "buildOption": {  
  },
  "targets": [  // 定义不同的target
    {
      "name": "default",  // 默认target名称default
      "runtimeOS": "HarmonyOS",
    },
    {
      "name": "free",  // 免费版target名称
      "runtimeOS": "HarmonyOS"
    },
    {
      "name": "pay",  // 付费版target名称
      "runtimeOS": "HarmonyOS",
    }
  ]
}

定义target产物的deviceType

  1. 每一个target均可以指定支持的设备类型deviceType
  2. 也可以不定义。如果不定义,则该target默认支持module.json5中定义的设备类型
  3. 在定义每个target的deviceType时,支持的设备类型必须在module.json5中已经定义
json 复制代码
{
  "apiType": 'stageMode',
  "buildOption": {
  },
  "targets": [
    {
      "name": "default",  //未定义deviceType,默认支持config.json或module.json5中定义的设备类型
      "runtimeOS": "HarmonyOS",
    },
    {
      "name": "free",
      "runtimeOS": "HarmonyOS",
      "config": {
        "deviceType": [  //定义free支持的设备类型为phone
          "phone"
        ]
      }
    },
    {
      "name": "pay",
      "runtimeOS": "HarmonyOS",
      "config": {
        "deviceType": [  //定义pay支持的设备类型为phone
          "phone"
        ]
      }
    }
  ]
}

定义target产物的source源码集

Stage模型支持对pages源码目录的page页面进行定制

如下,在模块的pages目录下分别定义了index.ets、page1.ets和page2.ets三个页面。其中default使用了index.ets页面;free使用了index.ets和page1.ets页面;pay使用了index.ets和page2.ets页面

json 复制代码
{
  "apiType": 'stageMode',
  "buildOption": {
  },
  "targets": [
    {
      "name": "default",
      "runtimeOS": "HarmonyOS",
      "source": {  //定义Stage模型中默认版target的pages源码文件
        "pages": [
          "pages/index"
        ]
      }
    },
    {
      "name": "free",
      "runtimeOS": "HarmonyOS",
      "config": {
        "deviceType": [
          "phone"
        ]
      },
      "source": {  //定义Stage模型中免费版target的pages源码文件
        "pages": [
          "pages/index",
          "pages/page1"
        ]
      }
    },
    {
      "name": "pay",
      "runtimeOS": "HarmonyOS",
      "config": {
        "deviceType": [
          "phone"
        ]
      },
      "source": {  //定义Stage模型中付费版target的pages源码文件
        "pages": [
          "pages/index",
          "pages/page2"
        ]
      }
    }
  ]
}

定义target产物的资源resource

  1. 将每个target所使用的资源存放在不同的资源目录下以作区分
  2. ArkTS工程支持对main目录下的资源文件目录(resource)进行定制
  3. 如果target引用的多个资源文件目录下,存在同名的资源,则在构建打包过程中,将按照配置的资源文件目录顺序进行选择,也就是说优先选择前面定义的
json 复制代码
{
  "apiType": 'stageMode',
  "buildOption": {
  },
  "targets": [
    {
      "name": "default",
      "runtimeOS": "HarmonyOS",
      "source": {
        "pages": [
          "pages/index"
        ]
      },
      "resource": {  //定义默认版target使用的资源文件目录
        "directories": [
          "./src/main/resources_default"
        ]
      }
    },
    {
      "name": "free",
      "runtimeOS": "HarmonyOS",
      "config": {
        "deviceType": [
          "phone"
        ]
      },
      "source": {  
        "pages": [
          "pages/index",
          "pages/page1"
        ]
      },
      "resource": {  //定义免费版target使用的资源文件目录
        "directories": [
          "./src/main/resources_default",
          "./src/main/resources_free"
        ]
      }
    },
    {
      "name": "pay",
      "runtimeOS": "HarmonyOS",
      "config": {
        "deviceType": [
          "phone"
        ]
      },
      "source": {  
        "pages": [
          "pages/index",
          "pages/page2"
        ]
      },
      "resource": {  //定义付费版target使用的资源文件目录,该功能在API 9及以上版本的工程中生效
        "directories": [
          "./src/main/resources_default",
          "./src/main/resources_pay"
        ]
      }
    }
  ]
}

定义target产物C++工程依赖的.so文件

这部分有C++经验的去看吧。因为我们一般都是ets开发,这部分涉及的少

定义target产物的distroFilter

目前只有API8的工程支持这些,先略过

配置APP多product构建产物

APP用于应用/服务上架发布,针对不同的应用场景,可以定制不同的product,每个product中支持对bundleName、签名信息以及包含的target进行定制

定义多project产物的products

  1. 每一个product对应一个定制的APP包,因此,在定制APP多目标构建产物前,应提前规划好需要定制的product名称
  2. 在定制product时,必须存在"default"的product,否则编译时会出现错误
json 复制代码
  "app": {
    "signingConfigs": [],
    "compileSdkVersion": 9,
    "compatibleSdkVersion": 9,
    "products": [
      {
        "name": "default",  //默认的product,不可更改名称
      },
      {
        "name": "productA",  //定制的productA
      }, 
      {
        "name": "productB",  //定制的productB
      }
    ]
  }

定义product产物的bundleName信息

针对每个定义的product,均可以定制不同的bundleName,如果product未定义bundleName,则采用工程默认的bundleName

json 复制代码
"app": {
    "signingConfigs": [],
    "compileSdkVersion": 9,
    "compatibleSdkVersion": 9,
    "products": [
      {
        "name": "default",
        "bundleName": "com.example00.com"  //定义default的bundleName信息
      },
      {
        "name": "productA",
        "bundleName": "com.example01.com"  //定义productA的bundleName信息
      },
      {
        "name": "productB",
        "bundleName": "com.example02.com"  //定义productB的bundleName信息
      }
    ]
  }

定义product的签名配置信息

  1. 针对每个定义的product,均可以定制不同的signingConfig签名文件,如果product未定义signingConfig,则构建生成未签名的APP包
  2. 通常情况下,您首先需要在签名配置界面或工程的build-profile.json5文件中配置签名信息

例如在File > Project Structure > Project > Signing Configs界面,分别配置default、product_A和product_B的签名信息

签名信息配置完成后,再添加各个product对应的签名文件,示例如下所示

您也可以提前在product中定义签名文件信息,然后在签名界面对每个product进行签名,确保配置的product签名文件与签名界面配置的签名文件保持一致即可

json 复制代码
"app": {
    "signingConfigs": [],
    "compileSdkVersion": 9,
    "compatibleSdkVersion": 9,
    "products": [
      {
        "name": "default",
        "bundleName": "com.example00.com",
        "signingConfig": "default"  //定义default的签名文件信息
      },
      {
        "name": "productA",
        "bundleName": "com.example01.com",
        "signingConfig": "productA"  //定义productA的签名文件信息
      },
      {
        "name": "productB",
        "bundleName": "com.example02.com",
        "signingConfig": "productB"  //定义productB的签名文件信息
      }
    ]
  }

定义product产物包含的target

  1. 开发者可以选择将定义的target打包到哪一个product中
  2. 每个product可以指定一个或多个target
  3. 每个target也可以打包到不同的product中,但是同一个module的不同target不能打包到同一个product中

例如,前面定义了default、free和pay三个target,现需要将default target打包到default product中;将free target打包到productA中;将pay target打包到productB中

json 复制代码
{
  "app": {
    "signingConfigs": [
      {
        "name": "productB",
        "type": "HarmonyOS",
        "material": {
          "storePassword": "000000190F49B79861A613EF0D4F24A6F9D52A7EB18CBDC590F8A7D48244508D0B3896E8D0B9DC7F17",
          "certpath": "D:/key/Release/myApplication_release.cer",
          "keyAlias": "myApplication",
          "keyPassword": "00000019111E2366391063DFB79F132A48D666374E1D2FA8E2744EF62E9DDC44245F443F5738FEF242",
          "profile": "D:/key/Release/myApplication_release Provision.p7b",
          "signAlg": "SHA256withECDSA",
          "storeFile": "D:/key/Release/myApplication_release.p12"
        }
      }
    ],
    "compileSdkVersion": 9,
    "compatibleSdkVersion": 9,
    "products": [
      {
        "name": "default",
        "bundleName": "com.example00.com",
        "signingConfig": "default"
      },
      {
        "name": "productA",
        "bundleName": "com.example01.com",
        "signingConfig": "productA"
      },
      {
        "name": "productB",
        "bundleName": "com.example02.com",
        "signingConfig": "productB"
      }
    ]
  },
  "modules": [
    {
      "name": "entry",
      "srcPath": "./entry",
      "targets": [
        {
          "name": "default",  //将default target打包到default APP中
          "applyToProducts": [
            "default"
          ]
        },
        {
          "name": "free",  //将free target打包到productA APP中
          "applyToProducts": [
            "productA"
          ]
        },
        {
          "name": "pay",  //将pay target打包到productB APP中
          "applyToProducts": [
            "productB"
          ]
        }
      ]
    }
  ]
}

构建定义的product产物

每个target对应一个HAP,每个product对应一个APP包,在编译构建时,如果存在多product或多target时,您可以指定编译具体的包

  1. 单击右上角的图标,指定需要打包的ProductTarget ,然后单击Apply保存。例如选择"ProductA"中,entry模块对应的"free"Target。
  • Product:选择需要构建的APP包。
  • Product Info:该APP包的BundleName和SigningConfig信息。
  • Target Select:选择各个模块的Target,该Target需要包含在定义的Product中才能选择,如果未包含则显示"No Target to apply"
  1. 执行编译构建APP/HAP的任务:
  • 单击菜单栏的Build > Build Hap(s)/APP(s) > Build APP(s) ,构建指定的Product对应的APP

例如,按照上述设置,此时DevEco Studio将构建生成ProductA的APP包。default和ProductB的APP均不会生成。

  • 单击菜单栏的Build > Build Hap(s)/APP(s) > Build Hap(s) ,构建指定Product下的所有Target对应发的HAP。

例如,按照上述配置,此时DevEco Studio将构建生成entry模块下default和free的HAP。

  • 如果您想将某个模块下的指定target打包生成HAP,可以在工程目录中,单击模块名,然后再单击Build > Ma ke Module '模块名 ',此时DevEco Studio将构建生成模块下指定target对应的包。

例如,按照上述配置,此时DevEco Studio将构建生成entry模块下free的HAP,不会生成default的HAP。

调试和运行指定的Target

  1. 使用DevEco Studio调试或运行应用/服务时,每个模块只能选择其中的一个target运行
  2. 可以通过单击右上角的图标,指定需要调试或运行的Product 下对应的Module Target ,然后单击Apply保存

在选择需要调试或运行的target时,需要注意选择该target所属的Product,否则将找不到可调试和运行的target

单工程多目标构建总结

资料

相关推荐
遇到困难睡大觉哈哈18 小时前
HarmonyOS —— Remote Communication Kit 拦截器(Interceptor)高阶定制能力笔记
笔记·华为·harmonyos
遇到困难睡大觉哈哈19 小时前
HarmonyOS —— Remote Communication Kit 定制处理行为(ProcessingConfiguration)速记笔记
笔记·华为·harmonyos
氤氲息19 小时前
鸿蒙 ArkTs 的WebView如何与JS交互
javascript·交互·harmonyos
遇到困难睡大觉哈哈19 小时前
HarmonyOS支付接入证书准备与生成指南
华为·harmonyos
赵浩生19 小时前
鸿蒙技术干货10:鸿蒙图形渲染基础,Canvas绘图与自定义组件实战
harmonyos
赵浩生19 小时前
鸿蒙技术干货9:deviceInfo 设备信息获取与位置提醒 APP 整合
harmonyos
BlackWolfSky20 小时前
鸿蒙暂未归类知识记录
华为·harmonyos
L、2181 天前
Flutter 与开源鸿蒙(OpenHarmony):跨平台开发的新未来
flutter·华为·开源·harmonyos
L、2181 天前
Flutter 与 OpenHarmony 深度融合实践:打造跨生态高性能应用(进阶篇)
javascript·flutter·华为·智能手机·harmonyos