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 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.ets。 852. 在启动框架配置文件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 116 1171. 在“ets/startup”路径下,依次创建6个启动任务文件。文件名称必须确保唯一性。本例中的6个文件名分别为StartupTask_001.ets~StartupTask_006.ets。 1182. 在启动框架配置文件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/>- true:手动模式。 <br/>- false:自动模式。<br/>**说明:**<br/> HSP、HAR中startupTask里的excludeFromAutoStart标签必须配置为true。 | 布尔值 | 该标签可缺省,缺省值为false。 | 193| runOnThread | 执行初始化所在的线程。<br/>- `mainThread`:在主线程中执行。<br/>- `taskPool`:在异步线程中执行。 | 字符串 | 该标签可缺省,缺省值为`mainThread`。 | 194| waitOnMainThread | 主线程是否需要等待启动框架执行。当runOnThread取值为`taskPool`时,该字段生效。 <br/>- true:主线程等待启动框架执行完之后,才会加载应用首页。 <br/>- 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 204 2051. 参考[Node-API](../napi/use-napi-process.md)创建so文件。本例中的6个so文件名称分别为libentry_001.so~libentry_006.so。 2062. 在启动框架配置文件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/>- true:手动模式。 <br/>- false:自动模式。<br/>**说明:**<br/> HSP、HAR中appPreloadHintStartupTask的excludeFromAutoStart标签必须配置为true。 | 布尔值 | 该标签可缺省,缺省值为false。| 275| runOnThread | 执行预加载所在的线程。<br/>- `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  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 ```