• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 应用启动框架AppStartup
2<!--Kit: Ability Kit-->
3<!--Subsystem: Ability-->
4<!--Owner: @yzkp-->
5<!--Designer: @yzkp-->
6<!--Tester: @lixueqing513-->
7<!--Adviser: @huipeizi-->
8
9## 概述
10
11应用启动时通常需要执行一系列初始化启动任务,如果将启动任务都放在[HAP](../quick-start/hap-package.md)的[UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md)组件的[onCreate](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#oncreate)生命周期中,那么只能在主线程中依次执行,不但影响应用的启动速度,而且当启动任务过多时,任务之间复杂的依赖关系还会使得代码难以维护。
12
13AppStartup提供了一种简单高效的应用启动方式,可以支持任务的异步启动,加快应用启动速度。同时,通过在一个配置文件中统一设置多个启动任务的执行顺序以及依赖关系,让执行启动任务的代码变得更加简洁清晰、容易维护。
14
15## 运行机制
16
17启动框架支持以自动模式或手动模式执行启动任务,默认采用自动模式。在构造[AbilityStage](ability-terminology.md#abilitystage)过程中开始加载开发者配置的启动任务,并执行自动模式的启动任务。开发者也可以在AbilityStage创建完后调用[startupManager.run](../reference/apis-ability-kit/js-apis-app-appstartup-startupManager.md#startupmanagerrun)方法,执行手动模式的启动任务。
18
19**图1** 启动框架执行时机
20
21![app-startup-procedure](figures/app-startup-procedure.png)
22
23
24## 支持的范围
25
26- HAP:entry类型的HAP支持以自动和手动模式启动。从API version 20开始,feature类型的HAP支持以自动和手动模式启动。
27
28- HSP/HAR: 从API version 18开始,支持在[HSP](../quick-start/in-app-hsp.md)和[HAR](../quick-start/har-package.md)中配置启动任务。HSP和HAR的启动任务、so预加载任务无法主动配置为自动模式,但可以被HAP中自动模式的启动任务、so预加载任务拉起。
29
30- 启动框架从API 18开始支持配置so预加载任务,so文件开发可以参考[Node-API](../napi/use-napi-process.md)创建Native C++工程。
31
32
33## 约束限制
34
35- 使用启动框架必须在[HAP](../quick-start/hap-package.md)的[module.json5配置文件](../quick-start/module-configuration-file.md)中开启启动框架。
36
37- ExtensionAbility组件启动场景单一,使用启动框架会带来额外开销,因此不支持ExtensionAbility组件启动时拉起启动框架。
38
39- 启动任务之间或so预加载任务之间不允许存在循环依赖。
40
41
42## 开发流程
43
441. [定义启动框架配置文件](#定义启动框架配置文件):在资源文件目录下创建并定义启动框架配置文件。
45   1. [创建启动框架配置文件](#创建启动框架配置文件):在资源文件目录下创建启动框架配置文件,并在[module.json5](../quick-start/module-configuration-file.md)配置文件中引用。
46   2. [定义启动参数配置](#定义启动参数配置):在启动框架配置文件中添加启动参数的配置信息。
47   3. [定义启动任务配置](#定义启动任务配置):在启动框架配置文件中添加启动任务的配置信息
48   4. [定义预加载so任务配置](#定义预加载so任务配置):在启动框架配置文件中添加预加载so任务的配置信息。
49
502. [设置启动参数](#设置启动参数):在启动参数文件中,设置超时时间和启动任务的监听器等参数。
513. [为每个待初始化功能组件添加启动任务](#为每个待初始化功能组件添加启动任务):通过实现[StartupTask](../reference/apis-ability-kit/js-apis-app-appstartup-startupTask.md)接口,启动框架将会按顺序执行初始化流程。
524. [可选操作](#可选操作):开发者可以在复杂场景下更精细地控制启动框架的行为。
53   - [HSP与HAR中使用启动框架](#hsp与har中使用启动框架):在HSP与HAR中配置启动任务、so预加载任务。实现跨模块的启动任务依赖管理,提升大型应用的启动效率和代码可维护性。
54   - [修改启动模式](#修改启动模式):将启动任务、so预加载任务修改为手动模式,灵活控制任务执行时机,避免不必要的启动开销。
55   - [添加任务匹配规则](#添加任务匹配规则):根据场景通过匹配规则过滤启动任务。精准控制任务执行范围,避免加载无关任务。
56
57
58## 定义启动框架配置文件
59
60### 创建启动框架配置文件
61
621. 在[HAP](../quick-start/hap-package.md)的“resources/base/profile”路径下,新建启动框架配置文件。文件名可以自定义,本文以"startup_config.json"为例。
63
642. 在[module.json5配置文件](../quick-start/module-configuration-file.md)的appStartup标签中,添加启动框架配置文件的索引。
65
66   module.json5示例代码如下。
67
68   ```json
69   {
70     "module": {
71       "name": "entry",
72       "type": "entry",
73       // ...
74       "appStartup": "$profile:startup_config", // 启动框架的配置文件
75       // ...
76     }
77   }
78   ```
79
80### 定义启动参数配置
81
82在启动框架配置文件startup_config.json中,可以添加启动参数的配置信息。
83
841. 在“ets/startup”路径下,创建启动参数配置文件。本例中的文件名为StartupConfig.ets852. 在启动框架配置文件startup_config.json中,添加启动参数配置文件的相关信息。
86
87   startup_config.json文件示例如下:
88
89   ```json
90   {
91     "startupTasks": [
92       // 启动任务
93     ],
94     "appPreloadHintStartupTasks": [
95       // 预加载so任务
96     ],
97     "configEntry": "./ets/startup/StartupConfig.ets" // 启动参数的配置
98   }
99   ```
100
101**表1** startup_config.json配置文件标签说明
102
103| 属性名称 | 含义 | 数据类型 | 是否可缺省 |
104| -------- | -------- | -------- | -------- |
105| startupTasks | 启动任务配置信息,详见[定义启动任务配置](#定义启动任务配置)。 | 对象数组 | 该标签可缺省,缺省值为空。 |
106| appPreloadHintStartupTasks | 预加载so任务配置信息,详见[定义预加载so任务配置](#定义预加载so任务配置)。 | 对象数组 | 该标签可缺省,缺省值为空。 |
107| configEntry | 启动参数配置文件所在路径。详见[设置启动参数](#设置启动参数)。<br/>**说明:**<br/>- HSP、HAR中不允许配置`configEntry`字段。<br/>- 如果应用开启了[文件名混淆](../arkts-utils/source-obfuscation.md#-enable-filename-obfuscation),则需要将文件路径添加到保留白名单中。具体操作详见[ArkGuard混淆原理及功能](../arkts-utils/source-obfuscation.md)的[-keep-file-name](../arkts-utils/source-obfuscation.md#-keep-file-name)部分。 | 字符串 | 该标签不可缺省。 |
108
109### 定义启动任务配置
110
111假设当前应用启动框架共包含6个启动任务,任务之间的依赖关系如下图所示。为了便于并发执行启动任务,单个启动任务文件包含的启动任务应尽量单一,本例中每个启动任务对应一个启动任务文件。
112
113**图2** 启动任务依赖关系图
114
115![app-startup-task](figures/app-startup-task.png)
116
1171. 在“ets/startup”路径下,依次创建6个启动任务文件。文件名称必须确保唯一性。本例中的6个文件名分别为StartupTask_001.ets~StartupTask_006.ets1182. 在启动框架配置文件startup_config.json中,添加启动任务配置。
119
120   startup_config.json文件示例如下:
121
122   ```json
123   {
124     "startupTasks": [
125       {
126         "name": "StartupTask_001",
127         "srcEntry": "./ets/startup/StartupTask_001.ets",
128         "dependencies": [
129           "StartupTask_002",
130           "StartupTask_003"
131         ],
132         "runOnThread": "taskPool",
133         "waitOnMainThread": false
134       },
135       {
136         "name": "StartupTask_002",
137         "srcEntry": "./ets/startup/StartupTask_002.ets",
138         "dependencies": [
139           "StartupTask_003",
140           "StartupTask_004"
141         ],
142         "runOnThread": "taskPool",
143         "waitOnMainThread": false
144       },
145       {
146         "name": "StartupTask_003",
147         "srcEntry": "./ets/startup/StartupTask_003.ets",
148         "dependencies": [
149           "StartupTask_004"
150         ],
151         "runOnThread": "taskPool",
152         "waitOnMainThread": false
153       },
154       {
155         "name": "StartupTask_004",
156         "srcEntry": "./ets/startup/StartupTask_004.ets",
157         "runOnThread": "taskPool",
158         "waitOnMainThread": false
159       },
160       {
161         "name": "StartupTask_005",
162         "srcEntry": "./ets/startup/StartupTask_005.ets",
163         "dependencies": [
164           "StartupTask_006"
165         ],
166         "runOnThread": "mainThread",
167         "waitOnMainThread": true,
168         "excludeFromAutoStart": true
169       },
170       {
171         "name": "StartupTask_006",
172         "srcEntry": "./ets/startup/StartupTask_006.ets",
173         "runOnThread": "mainThread",
174         "waitOnMainThread": false,
175         "excludeFromAutoStart": true
176       }
177     ],
178     "appPreloadHintStartupTasks": [
179       // 预加载so任务
180     ],
181     "configEntry": "./ets/startup/StartupConfig.ets"
182   }
183   ```
184
185**表2** startupTasks标签说明
186
187| 属性名称 | 含义 | 数据类型 | 是否可缺省 |
188| -------- | -------- | -------- | -------- |
189| name | 启动任务名称,可自定义,推荐与类名保持一致。 | 字符串 | 该标签不可缺省。 |
190| srcEntry | 启动任务对应的文件路径。<br/>**说明:** <br/> 如果应用开启了[文件名混淆](../arkts-utils/source-obfuscation.md#-enable-filename-obfuscation),则需要将文件路径添加到保留白名单中。具体操作详见[ArkGuard混淆原理及功能](../arkts-utils/source-obfuscation.md)的[-keep-file-name](../arkts-utils/source-obfuscation.md#-keep-file-name)部分。 | 字符串 | 该标签不可缺省。 |
191| dependencies | 启动任务依赖的其他启动任务的类名数组。 | 对象数组 | 该标签可缺省,缺省值为空。 |
192| excludeFromAutoStart | 是否排除自动模式,详细介绍可以查看[修改启动模式](#修改启动模式)。 <br/>-&nbsp;true:手动模式。 <br/>-&nbsp;false:自动模式。<br/>**说明:**<br/> HSP、HAR中startupTask里的excludeFromAutoStart标签必须配置为true。 | 布尔值 | 该标签可缺省,缺省值为false。 |
193| runOnThread | 执行初始化所在的线程。<br/>-&nbsp;`mainThread`:在主线程中执行。<br/>-&nbsp;`taskPool`:在异步线程中执行。 | 字符串 | 该标签可缺省,缺省值为`mainThread`。 |
194| waitOnMainThread | 主线程是否需要等待启动框架执行。当runOnThread取值为`taskPool`时,该字段生效。 <br/>-&nbsp;true:主线程等待启动框架执行完之后,才会加载应用首页。 <br/>-&nbsp;false:主线程不等待启动任务执行。 | 布尔值 | 该标签可缺省,缺省值为true。 |
195| matchRules | 该字段用于筛选需要以自动模式启动的启动任务,加速应用启动过程。适用于快速拉起某个页面的场景,例如,通过桌面卡片、通知或意图调用等方式触发的页面跳转,实现功能服务的一步直达体验。操作指导详见[添加任务匹配规则](#添加任务匹配规则)。<br/>**说明:** <br/>- 从API version 20开始,支持该字段。当前仅支持在HAP中配置该字段。<br/>- 该字段的优先级高于excludeFromAutoStart。如果所有启动任务均匹配失败,则按任务的excludeFromAutoStart配置处理。 | 对象 | 该标签可缺省。|
196
197### 定义预加载so任务配置
198
199假设当前应用启动框架共包含6个so预加载任务,任务之间的依赖关系如下图所示。不建议应用在so文件的加载回调中运行代码逻辑,so文件的加载不宜过长,否则会影响主线程的运行。
200
201**图3** so预加载任务依赖关系图
202
203![app-startup-so-task](figures/app-startup-so-task.png)
204
2051. 参考[Node-API](../napi/use-napi-process.md)创建so文件。本例中的6个so文件名称分别为libentry_001.so~libentry_006.so2062. 在启动框架配置文件startup_config.json中,添加预加载so任务配置。
207
208   startup_config.json文件示例如下:
209
210   ```json
211   {
212     "startupTasks": [
213       // 启动任务
214     ],
215     "appPreloadHintStartupTasks": [
216       {
217         "name": "libentry_001",
218         "srcEntry": "libentry_001.so",
219         "dependencies": [
220           "libentry_002",
221           "libentry_003"
222         ],
223         "runOnThread": "taskPool"
224       },
225       {
226         "name": "libentry_002",
227         "srcEntry": "libentry_002.so",
228         "dependencies": [
229           "libentry_003",
230           "libentry_004"
231         ],
232         "runOnThread": "taskPool"
233       },
234       {
235         "name": "libentry_003",
236         "srcEntry": "libentry_003.so",
237         "dependencies": [
238           "libentry_004"
239         ],
240         "runOnThread": "taskPool"
241       },
242       {
243         "name": "libentry_004",
244         "srcEntry": "libentry_004.so",
245         "runOnThread": "taskPool"
246       },
247       {
248         "name": "libentry_005",
249         "srcEntry": "libentry_005.so",
250         "dependencies": [
251           "libentry_006"
252         ],
253         "runOnThread": "taskPool",
254         "excludeFromAutoStart": true
255       },
256       {
257         "name": "libentry_006",
258         "srcEntry": "libentry_006.so",
259         "runOnThread": "taskPool",
260         "excludeFromAutoStart": true
261       }
262     ],
263     "configEntry": "./ets/startup/StartupConfig.ets"
264   }
265   ```
266
267**表3** appPreloadHintStartupTasks标签说明
268
269| 属性名称 | 含义 | 数据类型 | 是否可缺省 |
270| -------- | -------- | -------- | -------- |
271| name | 预加载so文件名。 | 字符串 | 该标签不可缺省。 |
272| srcEntry | 带后缀预加载so文件名。 | 字符串 | 该标签不可缺省。 |
273| dependencies | 预加载任务依赖的其他预加载任务的so名数组。 | 对象数组 | 该标签可缺省,缺省值为空。 |
274| excludeFromAutoStart | 是否排除自动模式,详细介绍可以查看[修改启动模式](#修改启动模式)。 <br/>-&nbsp;true:手动模式。 <br/>-&nbsp;false:自动模式。<br/>**说明:**<br/> HSP、HAR中appPreloadHintStartupTask的excludeFromAutoStart标签必须配置为true。 | 布尔值 | 该标签可缺省,缺省值为false。|
275| runOnThread | 执行预加载所在的线程。<br/>-&nbsp;`taskPool`:在异步线程中执行。<br/>**说明:**<br/> so预加载只允许在`taskPool`线程执行。 | 字符串 | 该标签不可缺省。 |
276| matchRules | 该字段用于筛选需要以自动模式启动的预加载so任务,加速应用启动过程。适用于快速拉起某个页面的场景,例如,通过桌面卡片、通知或意图调用等方式触发的页面跳转,实现功能服务的一步直达体验。操作指导详见[添加任务匹配规则](#添加任务匹配规则)。<br/>**说明:** <br/>- 从API version 20开始,支持该字段。当前仅支持在HAP中配置该字段。<br/>- 该字段的优先级高于excludeFromAutoStart。如果所有预加载so任务均匹配失败,则按任务的excludeFromAutoStart配置处理。 | 对象 | 该标签可缺省。|
277
278## 设置启动参数
279
280在启动参数配置文件(本文为“ets/startup/StartupConfig.ets”文件)中,使用[StartupConfigEntry](../reference/apis-ability-kit/js-apis-app-appstartup-startupConfigEntry.md)接口实现启动框架公共参数的配置,包括超时时间和启动任务的监听器等参数,其中需要用到如下接口:
281
282- [StartupConfig](../reference/apis-ability-kit/js-apis-app-appstartup-startupConfig.md):用于设置任务超时时间和启动框架的监听器。
283- [StartupListener](../reference/apis-ability-kit/js-apis-app-appstartup-startupListener.md):用于监听启动任务是否执行成功。
284
285```ts
286import { StartupConfig, StartupConfigEntry, StartupListener } from '@kit.AbilityKit';
287import { hilog } from '@kit.PerformanceAnalysisKit';
288import { BusinessError } from '@kit.BasicServicesKit';
289
290export default class MyStartupConfigEntry extends StartupConfigEntry {
291  onConfig() {
292    hilog.info(0x0000, 'testTag', `onConfig`);
293    let onCompletedCallback = (error: BusinessError<void>) => {
294      hilog.info(0x0000, 'testTag', `onCompletedCallback`);
295      if (error) {
296        hilog.error(0x0000, 'testTag', 'onCompletedCallback: %{public}d, message: %{public}s', error.code, error.message);
297      } else {
298        hilog.info(0x0000, 'testTag', `onCompletedCallback: success.`);
299      }
300    };
301    let startupListener: StartupListener = {
302      'onCompleted': onCompletedCallback
303    };
304    let config: StartupConfig = {
305      'timeoutMs': 10000,
306      'startupListener': startupListener
307    };
308    return config;
309  }
310}
311```
312
313
314## 为每个待初始化功能组件添加启动任务
315
316上述操作中已完成启动框架配置文件、启动参数的配置,还需要在每个功能组件对应的启动任务文件中,通过实现[StartupTask](../reference/apis-ability-kit/js-apis-app-appstartup-startupTask.md)来添加启动任务。其中,需要用到下面的两个方法:
317
318- [init](../reference/apis-ability-kit/js-apis-app-appstartup-startupTask.md#init):启动任务初始化。当该任务依赖的启动任务全部执行完毕,即onDependencyCompleted完成调用后,才会执行init方法对该任务进行初始化。
319- [onDependencyCompleted](../reference/apis-ability-kit/js-apis-app-appstartup-startupTask.md#ondependencycompleted):当前任务依赖的启动任务执行完成时,调用该方法。
320
321
322下面以[startup_config.json](#定义启动任务配置)中的StartupTask_001.ets文件为例,示例代码如下。开发者需要分别为每个待初始化功能组件添加启动任务。
323
324> **说明:**
325>
326> 由于StartupTask采用了[Sendable协议](../arkts-utils/arkts-sendable.md#sendable协议),在继承该接口时,必须添加Sendable注解。
327
328```ts
329import { StartupTask, common } from '@kit.AbilityKit';
330import { hilog } from '@kit.PerformanceAnalysisKit';
331
332@Sendable
333export default class StartupTask_001 extends StartupTask {
334  constructor() {
335    super();
336  }
337
338  async init(context: common.AbilityStageContext) {
339    hilog.info(0x0000, 'testTag', 'StartupTask_001 init.');
340    return 'StartupTask_001';
341  }
342
343  onDependencyCompleted(dependence: string, result: Object): void {
344    hilog.info(0x0000, 'testTag', 'StartupTask_001 onDependencyCompleted, dependence: %{public}s, result: %{public}s',
345      dependence, JSON.stringify(result));
346  }
347}
348```
349
350## 可选操作
351
352 ### HSP与HAR中使用启动框架
353
354 通常大型应用会有多个[HSP](../quick-start/in-app-hsp.md)和[HAR](../quick-start/har-package.md),本节将提供一个应用示例,以展示如何在HSP包和HAR包中使用启动框架。该示例应用包括两个HSP包(hsp1、hsp2)和一个HAR包(har1),并且包含启动任务和so预加载任务。
355
356 开发步骤如下:
357
358  1. 除[HAP](../quick-start/hap-package.md)外,在HSP包和HAR包的“resources/base/profile”目录下创建启动框架配置文件,不同模块可以使用相同文件名,本文以"startup_config.json"为例。
359
360  2. 分别在各个模块的启动框架配置文件startup_config.json中, 添加对应的配置信息。
361
362        假设当前应用存在的启动任务与so预加载任务如下表所示。
363
364        **表4** 应用启动任务与so预加载任务说明
365        | 模块 | 启动任务 | so预加载任务 |
366        | ------- | -------------------------------- | -------------------------------- |
367        | entry | HAP_Task_01 | libentry_01 |
368        | hsp1 | HSP1_Task_01 <br/> HSP1_Task_02 | libhsp1_01 <br/> libhsp1_02 |
369        | hsp2 | HSP2_Task_01 | libhsp2_01 |
370        | har | HAR1_Task_01 | libhar1_01 |
371
372        **图4** 启动任务与so预加载依赖关系图
373
374        ![app-startup](figures/hsp-har-startup.png)
375
376        [HAP](../quick-start/hap-package.md)的startup_config.json可参考[定义启动任务配置](#定义启动任务配置),HSP与HAR的startup_config.json文件无法配置"configEntry"字段,以hsp1包配置文件为例,示例如下:
377
378        ```json
379        {
380          "startupTasks": [
381            {
382              "name": "HSP1_Task_01",
383              "srcEntry": "./ets/startup/HSP1_Task_01.ets",
384              "dependencies": [
385                "HSP1_Task_02",
386                "HAR1_Task_01"
387              ],
388              "runOnThread": "taskPool",
389              "waitOnMainThread": false,
390              "excludeFromAutoStart": true
391            }
392          ],
393          "appPreloadHintStartupTasks": [
394            {
395              "name": "libhsp1_01",
396              "srcEntry": "libhsp1_01.so",
397              "dependencies": [
398                "libhsp1_02",
399                "libhar1_01"
400              ],
401              "runOnThread": "taskPool",
402              "excludeFromAutoStart": true
403            }
404          ]
405        }
406        ```
407
408  3. 分别在各个模块的[module.json5配置文件](../quick-start/module-configuration-file.md)的appStartup标签中,添加启动框架配置文件的索引。
409
410        hsp1、hsp2以及har1的module.json5示例代码如下。
411
412        ```json
413        {
414          "module": {
415            "name": "hsp1",
416            "type": "shared",
417            // ...
418            "appStartup": "$profile:startup_config", // 启动框架的配置文件
419            // ...
420          }
421        }
422        ```
423        ```json
424        {
425          "module": {
426            "name": "hsp2",
427            "type": "shared",
428            // ...
429            "appStartup": "$profile:startup_config", // 启动框架的配置文件
430            // ...
431          }
432        }
433        ```
434        ```json
435        {
436          "module": {
437            "name": "har1",
438            "type": "har",
439            // ...
440            "appStartup": "$profile:startup_config", // 启动框架的配置文件
441            // ...
442          }
443        }
444        ```
445
446  其余步骤请参考[设置启动参数](#设置启动参数)和[为每个待初始化功能组件添加启动任务](#为每个待初始化功能组件添加启动任务)章节进行配置。
447
448
449### 修改启动模式
450
451AppStartup分别提供了自动和手动两种方式来执行启动任务,entry模块中默认采用自动模式,开发者可以根据需要修改为手动模式,HSP与HAR只能配置为手动模式。
452
453- 自动模式:当AbilityStage完成创建后,自动执行启动任务。
454- 手动模式:在UIAbility完成创建后手动调用,来执行启动任务与so预加载任务。对于某些使用频率不高的模块,不需要应用最开始启动时就进行初始化。开发者可以选择将该部分启动任务修改为手动模式,在应用启动完成后调用[startupManager.run](../reference/apis-ability-kit/js-apis-app-appstartup-startupManager.md#startupmanagerrun)方法来执行启动任务与so预加载任务。
455
456下面以UIAbility的onCreate生命周期中为例,介绍如何采用手动模式来启动任务,示例代码如下。
457
458```ts
459import { AbilityConstant, UIAbility, Want, startupManager } from '@kit.AbilityKit';
460import { hilog } from '@kit.PerformanceAnalysisKit';
461import { BusinessError } from '@kit.BasicServicesKit';
462
463export default class EntryAbility extends UIAbility {
464  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
465    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
466    let startParams = ['StartupTask_005', 'StartupTask_006'];
467    try {
468      startupManager.run(startParams).then(() => {
469        console.log(`StartupTest startupManager run then, startParams = ${JSON.stringify(startParams)}.`);
470      }).catch((error: BusinessError) => {
471        console.error(`StartupTest promise catch error, error = ${JSON.stringify(error)}.`);
472        console.error(`StartupTest promise catch error, startParams = ${JSON.stringify(startParams)}.`);
473      })
474    } catch (error) {
475      let errMsg = (error as BusinessError).message;
476      let errCode = (error as BusinessError).code;
477      console.error(`Startup catch error, errCode= ${errCode}.`);
478      console.error(`Startup catch error, errMsg= ${errMsg}.`);
479    }
480  }
481
482  // ...
483}
484```
485
486开发者还可以在页面加载完成后,在页面中调用启动框架手动模式,示例代码如下。
487
488```ts
489import { startupManager } from '@kit.AbilityKit';
490
491@Entry
492@Component
493struct Index {
494  @State message: string = "手动模式";
495  @State startParams1: Array<string> = ["StartupTask_006"];
496  @State startParams2: Array<string> = ["libentry_006"];
497
498  build() {
499    RelativeContainer() {
500      Button(this.message)
501        .id('AppStartup')
502        .fontSize(20)
503        .fontWeight(FontWeight.Bold)
504        .onClick(() => {
505          if (!startupManager.isStartupTaskInitialized("StartupTask_006") ) { // 判断是否已经完成初始化
506            startupManager.run(this.startParams1)
507          }
508          if (!startupManager.isStartupTaskInitialized("libentry_006") ) {
509            startupManager.run(this.startParams2)
510          }
511        })
512        .alignRules({
513          center: {anchor: '__container__', align: VerticalAlign.Center},
514          middle: {anchor: '__container__', align: HorizontalAlign.Center}
515        })
516    }
517    .height('100%')
518    .width('100%')
519  }
520}
521```
522
523### 添加任务匹配规则
524
525在通过卡片、通知、意图调用等方式拉起某个页面时,为了实现功能服务一步直达,可以通过添加matchRules匹配规则,仅加载与当前场景相关的部分启动任务,无需加载全部默认的自动启动任务,以提高启动性能。
526
527可以通过以下两种方式添加匹配规则:
528
529* 通过matchRules中的uris、actions、insightIntents字段,根据UIAbility启动时的uri、action或意图名称,匹配不同场景启动任务及预加载so任务。
530* 如果上述方式不能满足需求,可以通过matchRules中的customization自定义匹配规则。
531
532  **表5** matchRules标签说明
533
534  | 属性名称 | 含义 | 数据类型 | 是否可缺省 | 适用场景 |
535  | -------- | -------- | -------- | -------- | -------- |
536  | uris | 表示自动模式执行的任务的uri取值范围。当UIAbility启动时,会将[Want](../reference/apis-ability-kit/js-apis-app-ability-want.md)中携带的uri属性,与此处配置的uris数组取值进行匹配。格式为`scheme://host/path`,uri中的其它内容会被忽略(如port、fragment等)。 | 字符串数组 | 可缺省,缺省值为空。 | 通过特定uri拉起UIAbility的场景。 |
537  | actions | 表示自动模式执行的任务的action取值范围。当UIAbility启动时,会将[Want](../reference/apis-ability-kit/js-apis-app-ability-want.md)中携带的action属性,与此处配置的actions数组取值进行匹配。 | 字符串数组 | 可缺省,缺省值为空。 | 通过特定action拉起UIAbility的场景。 |
538  | insightIntents | 表示自动模式执行的任务的意图名称取值范围。当UIAbility启动时,会将意图名称与此处配置的insightIntents数组取值进行匹配。 | 字符串数组 | 可缺省,缺省值为空。 | 通过特定意图名称拉起UIAbility的场景。 |
539  | customization | 表示自动模式执行的任务的自定义规则取值范围。通过实现StartupConfigEntry的[onRequestCustomMatchRule](../reference/apis-ability-kit/js-apis-app-appstartup-startupConfigEntry.md#startupconfigentryonrequestcustommatchrule20)接口返回自定义规则值。当UIAbility启动时,会将自定义规则值与此处配置的customization数组取值进行匹配。<br/>**说明:**<br/>仅支持startupTasks中的任务配置。 | 字符串数组 | 可缺省,缺省值为空。 | 如果使用uris、actions、insightIntents字段无法满足要求,可以使用customization自定义规则。 |
540
541  > **说明:**
542  >
543  > * uris、insightIntents、actions、customization任一属性匹配成功即为任务匹配成功。
544  > * 匹配成功的任务及其依赖任务都将在自动模式执行。
545  > * 所有任务均匹配失败,则按任务的excludeFromAutoStart配置处理。
546
547下面以uri匹配(action和意图名称类似)和customization匹配来举例,介绍如何实现添加任务匹配规则来筛选启动任务。
548
549**场景1:uri匹配**
550
551假定需要用户点击通知消息跳转到通知详情页面时,仅自动执行StartupTask_004和libentry_006任务。若启动通知详情UIAbility时Want中的uri属性为`test://com.example.startupdemo/notification`,可以通过uri匹配。示例如下:
552
5531. 对[定义启动任务配置](#定义启动任务配置)步骤中的startup_config.json文件进行修改,增加StartupTask_004任务和libentry_006任务的matchRules配置。
554
555    ```json
556    {
557      "startupTasks": [
558        {
559          "name": "StartupTask_004",
560          "srcEntry": "./ets/startup/StartupTask_004.ets",
561          "runOnThread": "taskPool",
562          "waitOnMainThread": false,
563          "matchRules": {
564            "uris": [
565              "test://com.example.startupdemo/notification"
566            ]
567          }
568        },
569      ],
570      "appPreloadHintStartupTasks": [
571        {
572          "name": "libentry_006",
573          "srcEntry": "libentry_006.so",
574          "runOnThread": "taskPool",
575          "excludeFromAutoStart": true,
576          "matchRules": {
577            "uris": [
578              "test://com.example.startupdemo/notification"
579            ]
580          }
581        }
582      ],
583      "configEntry": "./ets/startup/StartupConfig.ets"
584    }
585    ```
586
587**场景2:customization匹配**
588
589假定需要用户点击天气卡片跳转到天气界面时,仅自动执行StartupTask_006启动任务和excludeFromAutoStart=false配置的预加载so任务。若启动天气UIAbility时Want中传入的自定义参数`fromType`为`card`,可以通过customization匹配。示例如下:
590
591  1. 对[设置启动参数](#设置启动参数)步骤中的MyStartupConfigEntry.ets文件进行修改,新增[onRequestCustomMatchRule](../reference/apis-ability-kit/js-apis-app-appstartup-startupConfigEntry.md#startupconfigentryonrequestcustommatchrule20)方法。
592
593      ```ts
594      import { StartupConfig, StartupConfigEntry, StartupListener, Want } from '@kit.AbilityKit';
595      import { hilog } from '@kit.PerformanceAnalysisKit';
596      import { BusinessError } from '@kit.BasicServicesKit';
597
598      export default class MyStartupConfigEntry extends StartupConfigEntry {
599
600        // onConfig ...
601
602        onRequestCustomMatchRule(want: Want): string {
603          if (want?.parameters?.fromType == 'card') {
604            return 'ruleCard';
605          }
606          return '';
607        }
608
609      }
610      ```
611
612  2. 对[定义启动任务配置](#定义启动任务配置)步骤中的startup_config.json文件进行修改,增加StartupTask_006任务的matchRules配置。预加载so任务不支持customization字段,按任务原有的excludeFromAutoStart配置处理。
613
614      ```json
615      {
616        "startupTasks": [
617          {
618            "name": "StartupTask_006",
619            "srcEntry": "./ets/startup/StartupTask_006.ets",
620            "runOnThread": "mainThread",
621            "waitOnMainThread": false,
622            "excludeFromAutoStart": true,
623            "matchRules": {
624              "customization": [
625                "ruleCard"
626              ]
627            }
628          }
629        ],
630        "configEntry": "./ets/startup/StartupConfig.ets"
631      }
632      ```