文章示意图

页面预览

前言

在 HarmonyOS Stage 模型中,module.json5 是模块的核心清单文件。它声明了模块的能力(abilities)、权限(requestPermissions)、设备类型(deviceTypes)、入口组件(mainElement)等关键信息。系统通过读取这个文件来决定如何加载、运行和管控应用。

本文将以开源鸿蒙笔友通信应用 xiexin 的 module.json5 为蓝本,详细剖析模块清单的各个字段,重点讲解 abilities 配置、skills 声明、权限申请,以及与应用商店审核相关的内容。

提示:本文假设你已经了解 HarmonyOS Stage 模型基础。如果还不熟悉,建议先阅读前三篇文章。

一、module.json5 的定位

module.json5 是 HarmonyOS 模块清单文件,每个模块(HAP)都对应一个 module.json5。它告诉系统:

  • 这个模块叫什么名字、是什么类型
  • 它支持哪些设备(手机、平板、2in1)
  • 它的入口能力(Ability)是什么
  • 它需要申请哪些权限
  • 它的页面路由表在哪里

对于 xiexin 项目,module.json5 位于:

entry/src/main/module.json5

这是 entry 模块(主模块)的清单文件。如果未来 xiexin 扩展出 settingsshare 等独立模块,每个模块都会有自己的 module.json5

二、xiexin 的 module.json5 完整内容

xiexin 的 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"]
          }
        ]
      }
    ],
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ]
  }
}

整个文件虽然只有 43 行,却涵盖了模块声明的全部关键字段。下面我们逐一拆解。

三、module 顶层字段详解

3.1 name 与 type

{
  "module": {
    "name": "entry",
    "type": "entry",
    // ...
  }
}
  • name:模块名称,必须与目录名一致。xiexin 的模块在 entry/ 目录下,所以 name 是 "entry"
  • type:模块类型,可选值为:
    • entry:主模块,应用安装后第一个加载的模块
    • feature:功能模块,按需加载
    • shared:共享模块,提供 HAR/HSP 包给其他模块使用

xiexin 当前只有主模块,所以 type 是 "entry"

3.2 description

"description": "$string:module_desc"

模块描述,使用 $string: 引用 resources/base/element/string.json 中的字符串资源。

提示:模块描述会显示在系统的"应用信息"页面,对用户可见。建议用简洁的语言描述模块用途,如"主功能模块"、"账号管理"等。

3.3 mainElement

"mainElement": "EntryAbility"

模块入口能力的名称,必须与 abilities 数组中某个 ability 的 name 字段一致。系统启动应用时,会找到这个 ability 并加载它的 UI。

如果 mainElement 指向一个不存在的 ability,应用启动时会崩溃。

3.4 deviceTypes

"deviceTypes": [
  "phone",
  "tablet",
  "2in1"
]

模块支持的设备类型,可选值:

设备类型 说明
phone 手机
tablet 平板
tv 智慧屏
car 车机
wearable 智能穿戴
2in1 二合一设备(笔记本/平板)
default 通用设备

xiexin 支持手机、平板和 2in1 三种设备类型,这是主流鸿蒙应用的常见配置。

提示:声明不支持的设备类型,应用市场会限制设备安装。例如只声明 phone,平板用户无法安装。

3.5 deliveryWithInstall

"deliveryWithInstall": true

是否在应用安装时同步安装该模块。

  • true:随应用一起安装(entry 模块必须为 true
  • false:按需安装(feature 模块可用)

xiexin 是 entry 模块,必须为 true

3.6 installationFree

"installationFree": false

是否支持免安装特性。

  • true:支持免安装(元服务能力)
  • false:必须安装后才能使用

xiexin 是普通应用,不涉及元服务,所以为 false

提示:如果设置 installationFree: true,模块将被视为元服务,需要单独的元服务签名和审核流程。

3.7 pages

"pages": "$profile:main_pages"

页面路由表引用,指向 resources/base/profile/main_pages.json 文件。

提示:这个字段的详细用法已在上一篇文章中讲解,这里不再赘述。

四、abilities 数组详解

abilities 数组是 module.json5 的核心,声明模块中所有的 UIAbility。xiexin 只有一个 EntryAbility:

"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"]
      }
    ]
  }
]

下面逐一解析每个字段。

4.1 name 与 srcEntry

"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets"
  • name:Ability 名称,在同一模块内必须唯一
  • srcEntry:Ability 实现文件路径,相对于模块根目录(entry/

注意路径约定:

  • 路径以 ./ets/ 开头(不是 ./src/main/ets/
  • 必须包含 .ets 后缀
  • 路径分隔符使用 /

4.2 description、icon、label

"description": "$string:EntryAbility_desc",
"icon": "$media:layered_image",
"label": "$string:EntryAbility_label"

这三个字段都是资源引用:

  • description:Ability 描述,对用户可见
  • icon:Ability 图标,显示在桌面启动器
  • label:Ability 名称,显示在桌面图标下方

xiexin 使用了 layered_image 资源类型。这是 HarmonyOS 提供的分层图标特性,允许图标在不同主题下自适应。

4.3 startWindowIcon 与 startWindowBackground

"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background"

应用启动时的视觉元素:

  • startWindowIcon:启动屏图标(系统在应用加载完成前显示)
  • startWindowBackground:启动屏背景色

这两个字段是冷启动体验优化的关键。系统在调用 EntryAbility.onCreate 之前,会先显示 startWindowIcon + startWindowBackground 组成的启动屏,避免用户看到白屏。

提示:startWindowIcon 建议使用简洁的纯色图标,避免复杂的渐变和阴影,因为系统可能不会精确还原设计细节。

4.4 exported

"exported": true

是否允许其他应用通过隐式 Want 调用该 ability。

  • true:可被其他应用调用(主入口 ability 必须为 true
  • false:仅限本应用内部调用

提示:从 API 9 开始,所有 ability 默认不可被其他应用调用。如果需要跨应用调用,必须显式声明 exported: true 并配置 skills

4.5 skills 数组

"skills": [
  {
    "entities": ["entity.system.home"],
    "actions": ["action.system.home"]
  }
]

skills 声明 ability 可以响应的隐式 Want 类型。每个 skill 包含:

  • entities:Want 实体类别列表
  • actions:Want 动作列表
  • uris:Want URI 匹配规则(可选)

xiexin 配置的 skill 是:

  • entity.system.home + action.system.home

这是桌面启动器入口的固定配置。系统启动器会查找所有声明了这个 skill 的 ability,并在桌面显示图标。点击图标即启动该 ability。

五、requestPermissions 权限申请

xiexin 申请了一个权限:

"requestPermissions": [
  {
    "name": "ohos.permission.INTERNET"
  }
]

ohos.permission.INTERNET网络访问权限,属于 normal 级别(普通权限),用户无需手动授权,系统在应用安装时自动授予。

5.1 权限的三个等级

HarmonyOS 权限分为三个等级:

等级 说明 申请方式
normal 普通权限,涉及风险低 安装时自动授予
system_basic 系统基础权限,涉及敏感数据 运行时向用户申请
system_core 系统核心权限,仅系统应用可用 需签名配置

5.2 完整的权限申请结构

除了 name,权限申请还可以包含其他字段:

"requestPermissions": [
  {
    "name": "ohos.permission.READ_MEDIA",
    "reason": "$string:read_media_reason",
    "usedScene": {
      "abilities": ["EntryAbility"],
      "when": "inuse"
    }
  }
]

字段说明:

  • name:权限名称(必须)
  • reason:申请权限的说明,引用字符串资源(system_basic 权限必须)
  • usedScene:使用场景
    • abilities:使用该权限的 ability 名称列表
    • when:权限使用时机,可选 inuse(使用时)、always(始终)

5.3 xiexin 未来需要申请的权限

随着 xiexin 功能扩展,未来可能需要申请的权限包括:

权限名称 用途 等级
ohos.permission.READ_MEDIA 读取相册选头像 system_basic
ohos.permission.WRITE_MEDIA 保存信件截图到相册 system_basic
ohos.permission.NOTIFICATION_CONTROLLER 推送新信提醒 system_basic
ohos.permission.LOCATION 笔友位置分享 system_basic

六、module.json5 与 main_pages.json 的协同

module.json5 的 pages 字段指向路由表:

"pages": "$profile:main_pages"

这个引用建立了一条强契约

  1. 编译期校验:hvigor 会校验 $profile:main_pages 是否存在
  2. 运行时加载:系统在加载 entry 模块时,读取 main_pages.json 注册路由
  3. 路由查找router.pushUrl({ url: 'pages/ComposePage' }) 在路由表中查找

如果这条契约被打破(如 main_pages.json 被删除),应用启动时会崩溃。

七、module.json5 与 EntryAbility 的契约

module.json5 的 abilities[0] 建立了与 EntryAbility 的契约:

"abilities": [
  {
    "name": "EntryAbility",                                  // 契约 1
    "srcEntry": "./ets/entryability/EntryAbility.ets",      // 契约 2
    "skills": [
      { "entities": ["entity.system.home"], "actions": ["action.system.home"] }  // 契约 3
    ]
  }
]
  • 契约 1name 必须与 EntryAbility 类名对应(虽然技术上不强制,但这是约定)
  • 契约 2srcEntry 必须指向真实的 .ets 文件
  • 契约 3skills 决定了桌面图标是否显示

如果 srcEntry 指向的文件不存在,或文件中没有 export default class XxxAbility extends UIAbility,应用无法启动。

八、module.json5 的扩展实践

让我们为 xiexin 添加一个设置 Ability,展示如何扩展 abilities 数组。

8.1 创建 SettingsAbility

// entry/src/main/ets/entryability/SettingsAbility.ets
import { UIAbility, AbilityConstant, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { hilog } from '@kit.PerformanceAnalysisKit';

const TAG: string = 'SettingsAbility';
const DOMAIN: number = 0xFF00;

export default class SettingsAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    hilog.info(DOMAIN, TAG, '%{public}s', 'SettingsAbility onCreate');
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    windowStage.loadContent('pages/SettingsPage', (err) => {
      if (err.code) {
        hilog.error(DOMAIN, TAG, 'Failed to load content: %{public}s',
          JSON.stringify(err) ?? '');
      }
    });
  }
}

8.2 注册到 module.json5

{
  "module": {
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        // ...
        "skills": [
          {
            "entities": ["entity.system.home"],
            "actions": ["action.system.home"]
          }
        ]
      },
      {
        "name": "SettingsAbility",
        "srcEntry": "./ets/entryability/SettingsAbility.ets",
        "description": "$string:SettingsAbility_desc",
        "icon": "$media:settings_icon",
        "label": "$string:SettingsAbility_label",
        "startWindowIcon": "$media:startIcon",
        "startWindowBackground": "$color:start_window_background",
        "exported": false
      }
    ]
  }
}

注意:

  • SettingsAbility 没有 skills,所以桌面不会显示独立图标
  • exported: false,仅限本应用内部启动

8.3 从 EntryAbility 启动 SettingsAbility

import { common, Want } from '@kit.AbilityKit';

// 在某个页面中
const context = getContext(this) as common.UIAbilityContext;
const want: Want = {
  bundleName: 'com.xiexin.letter',
  abilityName: 'SettingsAbility'
};
context.startAbility(want);

这样就完成了多 Ability 的扩展。

九、module.json5 与应用市场审核

module.json5 的某些字段直接影响应用市场审核结果。以下是几个关键点:

9.1 权限审核

应用市场会严格审核权限申请:

  1. 必要性:每个权限必须有合理用途
  2. 最小化:只申请必要的权限
  3. reason 字段:system_basic 权限必须提供 reason

提示:如果权限用途无法解释清楚,审核会被驳回。建议在 reason 中写明"用于[具体场景]"。

9.2 deviceTypes 审核

如果声明 tablet 但实际 UI 不适配平板,应用市场会提示用户。建议:

  • 声明所有测试通过的设备类型
  • 使用响应式布局适配不同尺寸

9.3 图标与启动屏审核

iconstartWindowIcon 需要满足:

  • 尺寸符合规范(建议 192x192)
  • 不含敏感内容
  • 不模仿系统应用图标

十、module.json5 与签名配置

module.json5 本身不包含签名信息,签名信息在工程级 build-profile.json5 中:

// build-profile.json5
{
  "app": {
    "signingConfigs": [
      {
        "name": "default",
        "type": "HarmonyOS",
        "material": {
          "certpath": "...",
          "keyAlias": "debugKey",
          "keyPassword": "...",
          "profile": "...",
          "signAlg": "SHA256withECDSA",
          "storeFile": "...",
          "storePassword": "..."
        }
      }
    ]
  }
}

签名配置与 module.json5 的关系:

  • 签名后的 HAP 包含一个 META-INF 目录,存储签名信息
  • 系统在安装时验证签名,未签名或签名错误的应用无法安装
  • 签名证书的 bundleName 必须与 AppScope/app.json5 的 bundleName 一致

总结

本文详细剖析了 HarmonyOS module.json5 模块清单文件的各个字段,重点讲解了 abilities 配置、skills 声明、权限申请,以及与应用市场审核相关的内容。

理解 module.json5 的关键是把握"五个契约":与目录结构的契约、与 EntryAbility 的契约、与 main_pages.json 的契约、与系统启动器的契约、与应用市场的契约。这五个契约环环相扣,共同构成了 HarmonyOS 应用模块声明的基础设施。

下一篇文章我们将深入 AppScope/app.json5,剖析应用级全局配置的实践。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐