羽球场边工具 HarmonyOS 元服务实战(02):App Linking/openLink 聚合链接交接 一、为什么把主应用跳转收敛为聚合链接元服务适合承接即时工具但更完整的记录、复盘或账户能力可以落在关联主应用。两者之间不应依赖硬编码的 ability 名称Index.ets 维护一个聚合链接常量由 context.openLink 发起请求。这样链接解析与目标应用选择交给 App Linking页面只处理用户能看到的结果。constDOMAIN:number0x0000;constJUMP_TAG:stringMainAppJump;constMAIN_APP_LINK:stringhttps://kuqideharmonyos.drcn.agconnect.link/2m4d;EntryComponentstruct Index{StaterecommendationExpanded:booleanfalse;StateshowJumpFailure:booleanfalse;StatejumpFailureMessage:string主应用链接暂不可用请稍后重试;openMainApp():void{constcontext:common.UIAbilityContextthis.getUIContext().getHostContext()ascommon.UIAbilityContext;constowner:Indexthis;this.showJumpFailurefalse;constcompletionHandler: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.showJumpFailuretrue;});}toggleRecommendation():void{三、失败提示为何不能遮住场边工具失败时 Index 页保留当前计分、排阵和费用入口只显示 showJumpFailure 控制的提示。这个选择避免用户因为关联应用不可用而丢失正在进行的场边操作。页面提示不是对目标应用已启动的冒充是否真正到达目标还必须通过系统行为和目标页面回读确认。this.showJumpFailurefalse;constcompletionHandler: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.showJumpFailuretrue;}};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{StaterecommendationExpanded:booleanfalse;StateshowJumpFailure:booleanfalse;StatejumpFailureMessage:string主应用链接暂不可用请稍后重试;openMainApp():void{constcontext:common.UIAbilityContextthis.getUIContext().getHostContext()ascommon.UIAbilityContext;constowner:Indexthis;this.showJumpFailurefalse;constcompletionHandler: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.showJumpFailuretrue;}};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、回调消息以及当前页是否仍可继续使用。任何跨应用完成态都必须由目标端明确返回或由共享合同回读。当目标应用未安装、链接失效或网络暂不可用时元服务应保留现有计分和配对界面。用户不需要因为一次外部跳转失败丢失本地操作提示可以解释下一步但不应该强制关闭正在使用的工具页。以后若为链接增加比赛标识或来源版本参数必须有白名单与兼容策略。目标端无法理解的新参数应忽略或给出明确提示而不是把任意字符串当作路由。这样链接升级后旧版本元服务仍有可预测的失败路径。回调日志的最小字段日志至少应包含链接常量、回调类型、消息和目标元素信息才能把解析失败与目标拒绝分开。不要把用户输入或敏感比赛信息直接写进日志跳转诊断只需要足以重现链接合同的字段。页面显示的失败文案保持简短详细原因留给受控日志读取。返回元服务后的状态无论请求被接受还是失败回到元服务都应能继续使用计分与费用工具。若未来目标应用确实修改了共享记录返回后再通过明确的合同刷新不能因为曾经点击过链接就假定比分或配对已经更新。这个约束使外部跳转保持可失败、可恢复。