一、先确认元服务能力属于模块而不是首页按钮

场边临时组局时,用户需要快速打开计分、排阵或费用计算,而不是先理解一套完整应用的导航。这里的低摩擦入口并不是在页面上加一个“极速启动”文案,而是由模块配置声明交付形态。把这一层写进 module.json5,运行时首页只负责工具选择,工程边界才清晰。

    ],
    "deliveryWithInstall": true,
    "installationFree": true,
    "metadata": [
      {
        "name": "client_id",
        "value": "6917606123842596563"
      }
    ],
    "querySchemes": [
      "https"
    ],
    "pages": "$profile:main_pages",
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        "description": "$string:EntryAbility_desc",
        "icon": "$media:icon",
        "label": "$string:EntryAbility_label",
        "startWindowIcon": "$media:startIcon",
        "startWindowBackground": "$color:start_window_background",
        "exported": true,

二、installationFree 与 deliveryWithInstall 表达什么

entry 模块同时声明 deliveryWithInstall 与 installationFree。前者描述模块随安装交付,后者允许系统按元服务能力处理入口;两项都位于 module 级配置,而不在 Index.ets 内部。若把它们误写成页面变量,即使卡片仍能渲染,也无法改变包的交付语义。

参与者 输入 输出或约束
模型或配置 稳定标识、模式或模块字段 给出可追溯的工程事实
服务或系统能力 经过归一化的请求 返回明确结果或失败原因
页面 回读后的结果 只渲染,不保存第二份事实
      "tablet"
    ],
    "deliveryWithInstall": true,
    "installationFree": true,
    "metadata": [
      {
        "name": "client_id",
        "value": "6917606123842596563"
      }
    ],
    "querySchemes": [
      "https"
    ],
    "pages": "$profile:main_pages",
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        "description": "$string:EntryAbility_desc",
        "icon": "$media:icon",
        "label": "$string:EntryAbility_label",
        "startWindowIcon": "$media:startIcon",
        "startWindowBackground": "$color:start_window_background",

三、首页工具如何避免承担分发判断

Index 页展示“羽球场边工具”、主应用工具箱、计分器等内容,并把点击分派到对应页面。它不判断安装包类型,也不拼装安装请求。这样计分状态、配对结果和费用输入仍是本地工具功能,分发和安装能力则由工程配置、签名及系统环境共同决定。

const MAIN_APP_LINK: string = 'https://kuqideharmonyos.drcn.agconnect.link/2m4d';

@Entry
@Component
struct Index {
  @State recommendationExpanded: boolean = false;
  @State showJumpFailure: boolean = false;
  @State jumpFailureMessage: string = '主应用链接暂不可用,请稍后重试';

  openMainApp(): void {
    const context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
    const owner: Index = this;
    this.showJumpFailure = false;
    const completionHandler: CompletionHandler = {
      onRequestSuccess(elementName: bundleManager.ElementName, message: string): void {
        hilog.info(DOMAIN, JUMP_TAG, 'OpenLink completion success, message: %{public}s, element: %{public}s',
          message, JSON.stringify(elementName));
      },
      onRequestFailure(elementName: bundleManager.ElementName, message: string): void {
        hilog.error(DOMAIN, JUMP_TAG, 'OpenLink completion failure, message: %{public}s, element: %{public}s',
          message, JSON.stringify(elementName));
        owner.jumpFailureMessage = '主应用链接暂不可用,请稍后重试';
        owner.showJumpFailure = true;

四、构建结果能验证哪些边界

本次对当前工程执行 assembleHap 已成功,说明配置能通过资源、ArkTS、打包与签名链路。构建成功并不等同于每个分发入口都在任意设备上可用:实际系统入口还会受到设备支持、账号和平台配置影响。文章只把源码配置与构建结果作为工程事实,不夸大为线上分发已完成。

情况 容易出现的错误 本文采用的处理
数据或配置缺项 伪造默认成功状态 停在可解释的失败或空态
页面重进 使用上一页残留对象 从模型、服务或系统重新回读
重复动作 再写一遍相同业务事实 由稳定入口或回调收敛
import { AppColors, AppSizes, AppText } from '../common/Theme';

@Component
@Entry
struct QuickScoringPage {
  @State playerA: string = 'A队';
  @State playerB: string = 'B队';
  @State scoreA: number = 0;
  @State scoreB: number = 0;
  @State history: ScoreMatch[] = [];
  @State finishedText: string = '';

  addScore(team: string, delta: number): void {
    if (team === 'A') {
      this.scoreA = Math.max(0, this.scoreA + delta);
    } else {
      this.scoreB = Math.max(0, this.scoreB + delta);
    }
  }

  reset(): void {
    this.scoreA = 0;
    this.scoreB = 0;

五、从入口到工具卡片的检查项

检查时先读取打包后的 module.json 中 installationFree 是否保留,再安装或启动正确 bundle,确认首页展示计分、排阵、费用三类工具入口;随后依次进入一个本地工具并返回首页,确认页面导航没有承担安装判断。配图只展示可控设备中的主页,不把它当作平台分发成功的证明。

验收阶段 实际动作 回读重点
前置确认 启动正确 bundle 或打开目标页 标题、入口与模块身份
主题操作 执行搜索、切换、完成或跳转 服务/系统返回的结果
重进检查 返回、重启或切换范围后再进入 事实没有依赖旧页面残留

六、实现边界与维护顺序

元服务入口的安装形态由模块配置决定;主页专注计分、排阵和费用工具,不把分发属性藏进页面点击逻辑。 新增需求时应先补齐模型、配置或服务合同,再调整页面入口;把同一个判断复制到多个组件,短期看似方便,后续会使结果无法回读。ArkTS 状态管理的基础机制可参考 HarmonyOS 官方文档

七、继续扩展时的约束

元服务工程最容易混淆的是能构建与能被目标系统入口识别。前者由当前工程的依赖、资源和签名流程决定,后者还依赖设备能力和平台配置。把两层分别写入验收记录,既不贬低成功构建的价值,也不会凭一个首页截图宣称所有分发条件已经成立。

首页的角色是把用户带到计分、排阵和费用计算,不应该顺便记录安装、分发或账户状态。场边操作通常节奏快,导航层越少越好;业务模块各自管理输入和结果,用户从工具返回时才能保留清晰的上下文。

新增原子服务能力时,先检查模块声明、入口路由和打包产物,再决定是否需要修改首页卡片。这个顺序把平台能力与产品功能隔离开,能减少一次分发配置调整误伤比赛工具的风险。

配置检查不要依赖文件名猜测

是否为元服务要看实际 module.json5 的 module 声明和打包产物,而不是目录名、图标名或首页文案。重命名项目不会改变 installationFree 的真实值,复制模板也可能留下不匹配的配置。把配置字段列入构建前检查,能在发布前发现这种表面一致、语义错误的问题。

本地工具的启动验收

启动后先确认 bundle 身份和主页标题,再点击一个明确的工具卡片,例如计分器。进入、操作、返回三个动作能证明路由与主页集成仍可用;它不证明聚合链接或平台上架状态。不同结论使用不同证据,是避免元服务文章夸大范围的关键。

实时计分动作回读

Logo

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

更多推荐