1# 使用Deep Linking实现应用间跳转 2 3采用Deep Linking进行跳转时,系统会根据接口中传入的uri信息,在本地已安装的应用中寻找到符合条件的应用并进行拉起。当匹配到多个应用时,会拉起应用选择框。 4 5## 实现原理 6 7Deep Linking基于隐式Want匹配机制中的uri匹配来查询、拉起目标应用。隐式Want的uri匹配规则详见[uri匹配规则](explicit-implicit-want-mappings.md#uri匹配规则)。 8 9 10## 目标应用操作指导 11 12### 配置module.json5文件 13 14为了能够支持被其他应用访问,目标应用需要在[module.json5配置文件](../quick-start/module-configuration-file.md)中配置[skills标签](../quick-start/module-configuration-file.md#skills标签)。 15 16> **说明:** 17> 18> skills标签下默认包含一个skill对象,用于标识应用入口。应用跳转链接不能在该skill对象中配置,需要创建独立的skill对象。如果存在多个跳转场景,需要在skills标签下创建不同的skill对象,否则会导致配置无法生效。 19> 20> Deep Linking中的scheme取值支持自定义,可以为任意不包含特殊字符、非ohos开头的字符串。通常不为https、http、file,否则会拉起默认的系统浏览器。 21 22 23配置示例如下: 24 25```json 26{ 27 "module": { 28 // ... 29 "abilities": [ 30 { 31 // ... 32 "skills": [ 33 { 34 "entities": [ 35 "entity.system.home" 36 ], 37 "actions": [ 38 "action.system.home" 39 ] 40 }, 41 { 42 "actions": [ 43 // actions不能为空,actions为空会造成目标方匹配失败。 44 "ohos.want.action.viewData" 45 ], 46 "uris": [ 47 { 48 // scheme必选,可以自定义,以link为例,需要替换为实际的scheme 49 "scheme": "link", 50 // host必选,配置待匹配的域名 51 "host": "www.example.com" 52 } 53 ] 54 } // 新增一个skill对象,用于跳转场景。如果存在多个跳转场景,需配置多个skill对象。 55 ] 56 } 57 ] 58 } 59} 60``` 61 62### 获取并解析拉起方传入的应用链接 63 64在目标应用的UIAbility的onCreate()或者onNewWant()生命周期回调中,获取、解析拉起方传入的应用链接。 65 66```ts 67// 以EntryAbility.ets为例 68import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 69import { url } from '@kit.ArkTS'; 70 71export default class EntryAbility extends UIAbility { 72 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 73 // 从want中获取传入的链接信息。 74 // 如传入的url为:link://www.example.com/programs?action=showall 75 let uri = want?.uri; 76 if (uri) { 77 // 从链接中解析query参数,拿到参数后,开发者可根据自己的业务需求进行后续的处理。 78 let urlObject = url.URL.parseURL(want?.uri); 79 let action = urlObject.params.get('action'); 80 // 例如,当action为showall时,展示所有的节目。 81 if (action === "showall") { 82 // ... 83 } 84 } 85 } 86} 87``` 88 89## 拉起方应用实现应用跳转 90 91下面通过三个案例,分别介绍如何使用[openLink()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextopenlink12)与[startAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)接口实现应用跳转,以及如何在[Web组件](../reference/apis-arkweb/ts-basic-components-web.md)中实现应用跳转。 92 93### 使用openLink实现应用跳转 94 95在[openLink](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextopenlink12)接口的link字段中传入目标应用的URL信息,并将options字段中的`appLinkingOnly`配置为`false`。 96 97 98示例代码如下: 99 100```ts 101import { common, OpenLinkOptions } from '@kit.AbilityKit'; 102import { BusinessError } from '@kit.BasicServicesKit'; 103import { hilog } from '@kit.PerformanceAnalysisKit'; 104 105const TAG: string = '[UIAbilityComponentsOpenLink]'; 106const DOMAIN_NUMBER: number = 0xFF00; 107 108@Entry 109@Component 110struct Index { 111 build() { 112 Button('start link', { type: ButtonType.Capsule, stateEffect: true }) 113 .width('87%') 114 .height('5%') 115 .margin({ bottom: '12vp' }) 116 .onClick(() => { 117 let context = this.getUIContext().getHostContext() as common.UIAbilityContext; 118 let link: string = "link://www.example.com"; 119 let openLinkOptions: OpenLinkOptions = { 120 appLinkingOnly: false 121 }; 122 123 try { 124 context.openLink(link, openLinkOptions) 125 .then(() => { 126 hilog.info(DOMAIN_NUMBER, TAG, 'open link success.'); 127 }).catch((err: BusinessError) => { 128 hilog.error(DOMAIN_NUMBER, TAG, `open link failed. Code is ${err.code}, message is ${err.message}`); 129 }); 130 } catch (paramError) { 131 hilog.error(DOMAIN_NUMBER, TAG, `Failed to start link. Code is ${paramError.code}, message is ${paramError.message}`); 132 } 133 }) 134 } 135} 136``` 137 138### 使用startAbility实现应用跳转 139 140[startAbility](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)接口是将应用链接放入want中,通过调用[隐式want匹配](explicit-implicit-want-mappings.md#隐式want匹配原理)的方法触发应用跳转。通过[startAbility](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)接口启动时,还需要调用方传入待匹配的action和entity。 141 142 143示例代码如下: 144 145```ts 146import { common, Want } from '@kit.AbilityKit'; 147import { BusinessError } from '@kit.BasicServicesKit'; 148import { hilog } from '@kit.PerformanceAnalysisKit'; 149 150const TAG: string = '[UIAbilityComponentsOpenLink]'; 151const DOMAIN_NUMBER: number = 0xFF00; 152 153@Entry 154@Component 155struct Index { 156 build() { 157 Button('start ability', { type: ButtonType.Capsule, stateEffect: true }) 158 .width('87%') 159 .height('5%') 160 .margin({ bottom: '12vp' }) 161 .onClick(() => { 162 let context = this.getUIContext().getHostContext() as common.UIAbilityContext; 163 let want: Want = { 164 uri: "link://www.example.com" 165 }; 166 167 try { 168 context.startAbility(want).then(() => { 169 hilog.info(DOMAIN_NUMBER, TAG, 'start ability success.'); 170 }).catch((err: BusinessError) => { 171 hilog.error(DOMAIN_NUMBER, TAG, `start ability failed. Code is ${err.code}, message is ${err.message}`); 172 }); 173 } catch (paramError) { 174 hilog.error(DOMAIN_NUMBER, TAG, `Failed to start ability. Code is ${paramError.code}, message is ${paramError.message}`); 175 } 176 }) 177 } 178} 179``` 180 181### 使用Web组件实现应用跳转 182 183Web组件需要跳转DeepLink链接应用时,可通过拦截回调[onLoadIntercept](../reference/apis-arkweb/ts-basic-components-web.md#onloadintercept10)中对定义的事件进行处理,实现应用跳转。 184 185示例代码如下: 186 187```ts 188// index.ets 189import { webview } from '@kit.ArkWeb'; 190import { BusinessError } from '@kit.BasicServicesKit'; 191import { common } from '@kit.AbilityKit'; 192 193@Entry 194@Component 195struct WebComponent { 196 controller: webview.WebviewController = new webview.WebviewController(); 197 198 build() { 199 Column() { 200 Web({ src: $rawfile('index.html'), controller: this.controller }) 201 .onLoadIntercept((event) => { 202 const url: string = event.data.getRequestUrl(); 203 if (url === 'link://www.example.com') { 204 (this.getUIContext().getHostContext() as common.UIAbilityContext).openLink(url) 205 .then(() => { 206 console.log('openLink success'); 207 }).catch((err: BusinessError) => { 208 console.error('openLink failed, err:' + JSON.stringify(err)); 209 }); 210 return true; 211 } 212 // 返回true表示阻止此次加载,否则允许此次加载 213 return false; 214 }) 215 } 216 } 217} 218``` 219 220前端页面代码: 221```html 222// index.html 223<!DOCTYPE html> 224<html> 225<head> 226 <meta charset="UTF-8"> 227</head> 228<body> 229<h1>Hello World</h1> 230<!--方式一、通过绑定事件window.open方法实现跳转--> 231<button class="doOpenLink" onclick="doOpenLink()">跳转其他应用一</button> 232<!--方式二、通过超链接实现跳转--> 233<a href="link://www.example.com">跳转其他应用二</a> 234</body> 235</html> 236<script> 237 function doOpenLink() { 238 window.open("link://www.example.com") 239 } 240</script> 241```