• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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```