App Linking/openLink 成功交接后的系统浏览器回读

一、为什么把主应用跳转收敛为聚合链接

元服务适合承接即时工具,但更完整的记录、复盘或账户能力可以落在关联主应用。两者之间不应依赖硬编码的 ability 名称;Index.ets 维护一个聚合链接常量,由 context.openLink 发起请求。这样链接解析与目标应用选择交给 App Linking,页面只处理用户能看到的结果。

const DOMAIN: number = 0x0000;
const JUMP_TAG: string = 'MainAppJump';
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));

二、openLink 的回调如何区分三种结果

openLink 使用 appLinkingOnly: false、hideFailureTipDialog: true,并注册 success、failure 和 nonAppLinking 三个回调。success 表示请求已经由系统接受;failure 会记录错误并展开页面内的失败提示;nonAppLinking 则说明链接没有按 App Linking 目标处理。三者不能合并成“点击后没反应”,否则排查没有落点。

参与者 输入 输出或约束
模型或配置 稳定标识、模式或模块字段 给出可追溯的工程事实
服务或系统能力 经过归一化的请求 返回明确结果或失败原因
页面 回读后的结果 只渲染,不保存第二份事实
    };
    hilog.info(DOMAIN, JUMP_TAG, 'Open main app aggregate link click, uri: %{public}s', MAIN_APP_LINK);
    context.openLink(MAIN_APP_LINK, {
      appLinkingOnly: false,
      hideFailureTipDialog: true,
      parameters: {
        target: 'toolbox',
        source: 'quickBadmintonTools'
      },
      completionHandler: completionHandler
    })
      .then(() => {
        hilog.info(DOMAIN, JUMP_TAG, 'OpenLink request accepted.');
      })
      .catch((error: BusinessError) => {
        hilog.error(DOMAIN, JUMP_TAG, 'Failed to open main app aggregate link, code: %{public}d, message: %{public}s',
          error.code, error.message);
        this.jumpFailureMessage = '主应用链接暂不可用,请稍后重试';
        this.showJumpFailure = true;
      });
  }

  toggleRecommendation(): void {

三、失败提示为何不能遮住场边工具

失败时 Index 页保留当前计分、排阵和费用入口,只显示 showJumpFailure 控制的提示。这个选择避免用户因为关联应用不可用而丢失正在进行的场边操作。页面提示不是对目标应用已启动的冒充;是否真正到达目标,还必须通过系统行为和目标页面回读确认。

    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;
      }
    };
    hilog.info(DOMAIN, JUMP_TAG, 'Open main app aggregate link click, uri: %{public}s', MAIN_APP_LINK);
    context.openLink(MAIN_APP_LINK, {
      appLinkingOnly: false,
      hideFailureTipDialog: true,
      parameters: {
        target: 'toolbox',
        source: 'quickBadmintonTools'
      },
      completionHandler: completionHandler
    })

四、参数边界如何避免把页面状态带进链接

调用处只传递链接与必要参数,不把计分板的大对象、临时文本或页面引用序列化进跳转合同。需要共享的数据应使用可验证的链接参数或后端合同;否则目标应用无法校验来源,元服务返回后也难以恢复正确状态。当前实现的范围是聚合链接请求和结果提示,不声称已经完成跨应用业务数据同步。

情况 容易出现的错误 本文采用的处理
数据或配置缺项 伪造默认成功状态 停在可解释的失败或空态
页面重进 使用上一页残留对象 从模型、服务或系统重新回读
重复动作 再写一遍相同业务事实 由稳定入口或回调收敛
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;
      }
    };
    hilog.info(DOMAIN, JUMP_TAG, 'Open main app aggregate link click, uri: %{public}s', MAIN_APP_LINK);
    context.openLink(MAIN_APP_LINK, {

五、验证跳转时必须回读什么

验证应从已安装的当前元服务包进入主页,展开推荐卡后点击“打开推荐应用”,观察本应用是否先产生成功、失败或非链接提示;若跳转到主应用,再读取目标页面和返回后的元服务状态;若链接不可解析,也要确认失败提示出现且本地工具仍可继续使用。本次 API 23 模拟器实测中,openLink 回调返回 Succeeded,目标元素为系统浏览器 com.huawei.hmos.browser/MainAbility;因此只能确认聚合链接已交给浏览器处理,不能声称关联主应用已经打开。配图对应该次交接后的可见结果。

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

六、实现边界与维护顺序

元服务通过聚合链接请求系统交接,成功、失败和留在当前页三种结果由 openLink 回调分别呈现。本次运行的成功回调指向系统浏览器 MainAbility,而非关联主应用;新增需求时应先补齐模型、配置或服务合同,再调整页面入口。ArkTS 状态管理的基础机制可参考 HarmonyOS 官方文档

七、继续扩展时的约束

链接跳转的成功回调表示系统受理请求,不等价于用户已经在目标应用完成了某项操作。页面日志与失败提示因此只描述自己观察到的事实:请求 URI、回调消息以及当前页是否仍可继续使用。任何跨应用完成态都必须由目标端明确返回或由共享合同回读。

当目标应用未安装、链接失效或网络暂不可用时,元服务应保留现有计分和配对界面。用户不需要因为一次外部跳转失败丢失本地操作;提示可以解释下一步,但不应该强制关闭正在使用的工具页。

以后若为链接增加比赛标识或来源版本,参数必须有白名单与兼容策略。目标端无法理解的新参数应忽略或给出明确提示,而不是把任意字符串当作路由。这样链接升级后,旧版本元服务仍有可预测的失败路径。

回调日志的最小字段

日志至少应包含链接常量、回调类型、消息和目标元素信息,才能把解析失败与目标拒绝分开。不要把用户输入或敏感比赛信息直接写进日志;跳转诊断只需要足以重现链接合同的字段。页面显示的失败文案保持简短,详细原因留给受控日志读取。

返回元服务后的状态

无论请求被接受还是失败,回到元服务都应能继续使用计分与费用工具。若未来目标应用确实修改了共享记录,返回后再通过明确的合同刷新;不能因为曾经点击过链接就假定比分或配对已经更新。这个约束使外部跳转保持可失败、可恢复。

Logo

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

更多推荐