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