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