1e41f4b71Sopenharmony_ci# AppStartup
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ci## Overview
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ciDuring application initialization, a series of startup tasks are triggered. If these tasks are concentratedly placed within the [onCreate](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityoncreate) lifecycle of the [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md) of the application's main module ([module](../quick-start/application-package-overview.md#module-types) of the entry type), they must be executed sequentially on the main thread, which significantly affects the application launch speed. In addition, when there are too many tasks, complex dependencies between them make the code difficult to maintain.
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ciAppStartup offers an efficient approach to application initialization. By enabling the asynchronous initiation of startup tasks, it ensures a smoother startup process. The centralized configuration of task execution order and interdependencies in a single file simplifies and clarifies the startup codebase, enhancing maintainability.
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ciAppStartup supports startup tasks in automatic or manual mode. By default, the automatic mode is used. After an [AbilityStage](../reference/apis-ability-kit/js-apis-app-ability-abilityStage.md) is created, the configured startup tasks are loaded and executed in automatic mode. You can also call [startupManager.run](../reference/apis-ability-kit/js-apis-app-appstartup-startupManager.md#startupmanagerrun) to execute the startup tasks in manual mode after a UIAbility is created.
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci**Figure 1** Startup procedure
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ci![app-startup-procedure](figures/app-startup-procedure.png)
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ci## Constraints
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ci- AppStartup can be used only in entry [modules](../quick-start/application-package-overview.md#module-types).
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ci- Circular dependencies are not allowed between startup tasks.
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci## Development Process
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ci1. [Defining an AppStartup Configuration File](#defining-an-appstartup-configuration-file): Create an AppStartup configuration file in the resource file directory, add the configuration about startup tasks, and reference the configuration file in [module.json5](../quick-start/module-configuration-file.md).
25e41f4b71Sopenharmony_ci2. [Setting Startup Parameters](#setting-startup-parameters): In the startup parameter file, set parameters such as the timeout interval and startup task listener.
26e41f4b71Sopenharmony_ci3. [Adding a Startup Task for Each Component to Be Initialized](#adding-a-startup-task-for-each-component-to-be-initialized): Implement the [StartupTask](../reference/apis-ability-kit/js-apis-app-appstartup-startupTask.md) interface.
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ci## How to Develop
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ci### Defining an AppStartup Configuration File
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ci1. Create a AppStartup configuration file in the **resources/base/profile** directory of the application's main module ([module](../quick-start/application-package-overview.md#module-types) of the entry type). The file name can be customized. The following uses **startup_config.json** as an example.
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ci2. In the **startup_config.json** file, add the configuration for each startup task in sequence.
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ci    It is assumed that the application has six startup tasks. The dependencies between the tasks are shown in the figure below. To facilitate concurrent execution of startup tasks, a startup task file should contain only one startup task. In this example, each startup task corresponds to a startup task file.
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ci    **Figure 2** Dependencies between startup tasks
39e41f4b71Sopenharmony_ci    
40e41f4b71Sopenharmony_ci    ![app-startup](figures/app-startup.png) 
41e41f4b71Sopenharmony_ci    
42e41f4b71Sopenharmony_ci    1. In the **ets/startup** directory, create six startup task files and a common startup parameter file. The file names must be unique.
43e41f4b71Sopenharmony_ci    
44e41f4b71Sopenharmony_ci        1. Create six startup task files. In this example, the six files are named from **StartupTask_001.ets** to **StartupTask_006.ets**.
45e41f4b71Sopenharmony_ci        2. Create a startup parameter file. In this example, the file name is **StartupConfig.ets**.
46e41f4b71Sopenharmony_ci        
47e41f4b71Sopenharmony_ci    2. Add the information about the startup task files and startup parameter file to the **startup_config.json** file.
48e41f4b71Sopenharmony_ci    
49e41f4b71Sopenharmony_ci        The following is an example of the **startup_config.json** file:
50e41f4b71Sopenharmony_ci        
51e41f4b71Sopenharmony_ci        ```json
52e41f4b71Sopenharmony_ci        {
53e41f4b71Sopenharmony_ci          "startupTasks": [
54e41f4b71Sopenharmony_ci            {
55e41f4b71Sopenharmony_ci              "name": "StartupTask_001",
56e41f4b71Sopenharmony_ci              "srcEntry": "./ets/startup/StartupTask_001.ets",
57e41f4b71Sopenharmony_ci              "dependencies": [
58e41f4b71Sopenharmony_ci                "StartupTask_002",
59e41f4b71Sopenharmony_ci                "StartupTask_003"
60e41f4b71Sopenharmony_ci              ],
61e41f4b71Sopenharmony_ci              "runOnThread": "taskPool",
62e41f4b71Sopenharmony_ci              "waitOnMainThread": false
63e41f4b71Sopenharmony_ci            },
64e41f4b71Sopenharmony_ci            {
65e41f4b71Sopenharmony_ci              "name": "StartupTask_002",
66e41f4b71Sopenharmony_ci              "srcEntry": "./ets/startup/StartupTask_002.ets",
67e41f4b71Sopenharmony_ci              "dependencies": [
68e41f4b71Sopenharmony_ci                "StartupTask_004"
69e41f4b71Sopenharmony_ci              ],
70e41f4b71Sopenharmony_ci              "runOnThread": "taskPool",
71e41f4b71Sopenharmony_ci              "waitOnMainThread": false
72e41f4b71Sopenharmony_ci            },
73e41f4b71Sopenharmony_ci            {
74e41f4b71Sopenharmony_ci              "name": "StartupTask_003",
75e41f4b71Sopenharmony_ci              "srcEntry": "./ets/startup/StartupTask_003.ets",
76e41f4b71Sopenharmony_ci              "dependencies": [
77e41f4b71Sopenharmony_ci                "StartupTask_004"
78e41f4b71Sopenharmony_ci              ],
79e41f4b71Sopenharmony_ci              "runOnThread": "taskPool",
80e41f4b71Sopenharmony_ci              "waitOnMainThread": false
81e41f4b71Sopenharmony_ci            },
82e41f4b71Sopenharmony_ci            {
83e41f4b71Sopenharmony_ci              "name": "StartupTask_004",
84e41f4b71Sopenharmony_ci              "srcEntry": "./ets/startup/StartupTask_004.ets",
85e41f4b71Sopenharmony_ci              "runOnThread": "taskPool",
86e41f4b71Sopenharmony_ci              "waitOnMainThread": false
87e41f4b71Sopenharmony_ci            },
88e41f4b71Sopenharmony_ci            {
89e41f4b71Sopenharmony_ci              "name": "StartupTask_005",
90e41f4b71Sopenharmony_ci              "srcEntry": "./ets/startup/StartupTask_005.ets",
91e41f4b71Sopenharmony_ci              "dependencies": [
92e41f4b71Sopenharmony_ci                "StartupTask_006"
93e41f4b71Sopenharmony_ci              ],
94e41f4b71Sopenharmony_ci              "runOnThread": "mainThread",
95e41f4b71Sopenharmony_ci              "waitOnMainThread": true,
96e41f4b71Sopenharmony_ci              "excludeFromAutoStart": true
97e41f4b71Sopenharmony_ci            },
98e41f4b71Sopenharmony_ci            {
99e41f4b71Sopenharmony_ci              "name": "StartupTask_006",
100e41f4b71Sopenharmony_ci              "srcEntry": "./ets/startup/StartupTask_006.ets",
101e41f4b71Sopenharmony_ci              "runOnThread": "mainThread",
102e41f4b71Sopenharmony_ci              "waitOnMainThread": false,
103e41f4b71Sopenharmony_ci              "excludeFromAutoStart": true
104e41f4b71Sopenharmony_ci            }
105e41f4b71Sopenharmony_ci          ],
106e41f4b71Sopenharmony_ci          "configEntry": "./ets/startup/StartupConfig.ets"
107e41f4b71Sopenharmony_ci        }
108e41f4b71Sopenharmony_ci        ```
109e41f4b71Sopenharmony_ci    
110e41f4b71Sopenharmony_ci        **Table 1** Fields in the startup_config.json file
111e41f4b71Sopenharmony_ci
112e41f4b71Sopenharmony_ci        | Field| Description| Data Type| Default Value Allowed|
113e41f4b71Sopenharmony_ci        | -------- | -------- | -------- | -------- |
114e41f4b71Sopenharmony_ci        | startupTasks | Configuration about the startup tasks. For details, see the following table.| Object array| No|
115e41f4b71Sopenharmony_ci        | configEntry | Path of the startup parameter file.| String| No|
116e41f4b71Sopenharmony_ci        
117e41f4b71Sopenharmony_ci        
118e41f4b71Sopenharmony_ci        **Table 2** Description of startupTasks
119e41f4b71Sopenharmony_ci
120e41f4b71Sopenharmony_ci        | Field| Description| Data Type| Default Value Allowed|
121e41f4b71Sopenharmony_ci        | -------- | -------- | -------- | -------- |
122e41f4b71Sopenharmony_ci        | name | Class name of the startup task.| String| No|
123e41f4b71Sopenharmony_ci        | srcEntry | Path of the file corresponding to the startup task.| String| No|
124e41f4b71Sopenharmony_ci        | dependencies | Array holding the class names of other startup tasks on which the startup task depends.| Object array| Yes (initial value: left empty)|
125e41f4b71Sopenharmony_ci        | excludeFromAutoStart | Whether to exclude the automatic mode. For details, see [Changing the Startup Mode](#optional-changing-the-startup-mode).<br>- **true**: manual mode.<br>- **false**: automatic mode.| Boolean| Yes (initial value: **false**)|
126e41f4b71Sopenharmony_ci        | runOnThread | Thread where the startup task is executed.<br>- **mainThread**: executed in the main thread.<br>- **taskPool**: executed in an asynchronous thread.| String| Yes (initial value: **mainThread**)|
127e41f4b71Sopenharmony_ci        | waitOnMainThread | Whether the main thread needs to wait until the startup task finishes execution. This parameter is valid only when **runOnThread** is set to **taskPool**.<br>- **true**: The main thread loads the application home page only the startup task finishes execution.<br>- **false**: The main thread does not wait for the startup task to finish execution.| Boolean| Yes (initial value: **true**)|
128e41f4b71Sopenharmony_ci        
129e41f4b71Sopenharmony_ci    3. Add the index of the AppStartup configuration file to the **appStartup** tag in the [module.json5 file](../quick-start/module-configuration-file.md).
130e41f4b71Sopenharmony_ci    
131e41f4b71Sopenharmony_ci        The following is an example of the **module.json5** file:
132e41f4b71Sopenharmony_ci    
133e41f4b71Sopenharmony_ci          ```json
134e41f4b71Sopenharmony_ci              {
135e41f4b71Sopenharmony_ci                "module": {
136e41f4b71Sopenharmony_ci                  "name": "entry",
137e41f4b71Sopenharmony_ci                  "type": "entry",
138e41f4b71Sopenharmony_ci                  // ...
139e41f4b71Sopenharmony_ci                  "appStartup": "$profile:startup_config," // AppStartup configuration file
140e41f4b71Sopenharmony_ci                  // ...
141e41f4b71Sopenharmony_ci                }
142e41f4b71Sopenharmony_ci              }
143e41f4b71Sopenharmony_ci          ```
144e41f4b71Sopenharmony_ci
145e41f4b71Sopenharmony_ci### Setting Startup Parameters
146e41f4b71Sopenharmony_ci
147e41f4b71Sopenharmony_ciIn the startup parameter file (**ets/startup/StartupConfig.ets** in this example), call [StartupConfigEntry](../reference/apis-ability-kit/js-apis-app-appstartup-startupConfigEntry.md) to set the common AppStartup parameters, including the timeout interval and listener.
148e41f4b71Sopenharmony_ci
149e41f4b71Sopenharmony_ci- [StartupConfig](../reference/apis-ability-kit/js-apis-app-appstartup-startupConfig.md): sets the task timeout interval and AppStartup listener.
150e41f4b71Sopenharmony_ci- [StartupListener](../reference/apis-ability-kit/js-apis-app-appstartup-startupListener.md): listens for the execution result of the startup task.
151e41f4b71Sopenharmony_ci
152e41f4b71Sopenharmony_ci```ts
153e41f4b71Sopenharmony_ciimport { StartupConfig, StartupConfigEntry, StartupListener } from '@kit.AbilityKit';
154e41f4b71Sopenharmony_ciimport { hilog } from '@kit.PerformanceAnalysisKit';
155e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit';
156e41f4b71Sopenharmony_ci
157e41f4b71Sopenharmony_ciexport default class MyStartupConfigEntry extends StartupConfigEntry {
158e41f4b71Sopenharmony_ci  onConfig() {
159e41f4b71Sopenharmony_ci    hilog.info(0x0000, 'testTag', `onConfig`);
160e41f4b71Sopenharmony_ci    let onCompletedCallback = (error: BusinessError<void>) => {
161e41f4b71Sopenharmony_ci      hilog.info(0x0000, 'testTag', `onCompletedCallback`);
162e41f4b71Sopenharmony_ci      if (error) {
163e41f4b71Sopenharmony_ci        hilog.info(0x0000, 'testTag', 'onCompletedCallback: %{public}d, message: %{public}s', error.code, error.message);
164e41f4b71Sopenharmony_ci      } else {
165e41f4b71Sopenharmony_ci        hilog.info(0x0000, 'testTag', `onCompletedCallback: success.`);
166e41f4b71Sopenharmony_ci      }
167e41f4b71Sopenharmony_ci    };
168e41f4b71Sopenharmony_ci    let startupListener: StartupListener = {
169e41f4b71Sopenharmony_ci      'onCompleted': onCompletedCallback
170e41f4b71Sopenharmony_ci    };
171e41f4b71Sopenharmony_ci    let config: StartupConfig = {
172e41f4b71Sopenharmony_ci      'timeoutMs': 10000,
173e41f4b71Sopenharmony_ci      'startupListener': startupListener
174e41f4b71Sopenharmony_ci    };
175e41f4b71Sopenharmony_ci    return config;
176e41f4b71Sopenharmony_ci  }
177e41f4b71Sopenharmony_ci}
178e41f4b71Sopenharmony_ci```
179e41f4b71Sopenharmony_ci
180e41f4b71Sopenharmony_ci### Adding a Startup Task for Each Component to Be Initialized
181e41f4b71Sopenharmony_ci
182e41f4b71Sopenharmony_ciThrough the preceding operations, you have configured the AppStartup configuration file and startup parameters. Now you need to implement [StartupTask](../reference/apis-ability-kit/js-apis-app-appstartup-startupTask.md) in each startup task file by calling the following two APIs:
183e41f4b71Sopenharmony_ci
184e41f4b71Sopenharmony_ci- [init](../reference/apis-ability-kit/js-apis-app-appstartup-startupTask.md#startuptaskinit): starts task initialization. Call **init** to initialize a task only after all startup tasks on which the task depends are executed, that is, after **onDependencyCompleted** is invoked.
185e41f4b71Sopenharmony_ci- [onDependencyCompleted](../reference/apis-ability-kit/js-apis-app-appstartup-startupTask.md#startuptaskondependencycompleted): invoked when the startup task on which the current task depends is complete.
186e41f4b71Sopenharmony_ci
187e41f4b71Sopenharmony_ci
188e41f4b71Sopenharmony_ciThe following uses the **StartupTask_001.ets** file in [startup_config.json](#defining-an-appstartup-configuration-file) as an example. You must add a startup task for each component to be initialized.
189e41f4b71Sopenharmony_ci
190e41f4b71Sopenharmony_ci> **NOTE**
191e41f4b71Sopenharmony_ci> 
192e41f4b71Sopenharmony_ci> **StartupTask** follows the [Sendable](../arkts-utils/arkts-sendable.md) protocol. Therefore, the Sendable annotation must be added when this API is inherited.
193e41f4b71Sopenharmony_ci
194e41f4b71Sopenharmony_ci```ts
195e41f4b71Sopenharmony_ciimport { StartupTask, common } from '@kit.AbilityKit';
196e41f4b71Sopenharmony_ciimport { hilog } from '@kit.PerformanceAnalysisKit';
197e41f4b71Sopenharmony_ci
198e41f4b71Sopenharmony_ci@Sendable
199e41f4b71Sopenharmony_ciexport default class StartupTask_001 extends StartupTask {
200e41f4b71Sopenharmony_ci  constructor() {
201e41f4b71Sopenharmony_ci    super();
202e41f4b71Sopenharmony_ci  }
203e41f4b71Sopenharmony_ci
204e41f4b71Sopenharmony_ci  async init(context: common.AbilityStageContext) {
205e41f4b71Sopenharmony_ci    hilog.info(0x0000, 'testTag', 'StartupTask_001 init.');
206e41f4b71Sopenharmony_ci    return 'StartupTask_001';
207e41f4b71Sopenharmony_ci  }
208e41f4b71Sopenharmony_ci
209e41f4b71Sopenharmony_ci  onDependencyCompleted(dependence: string, result: Object): void {
210e41f4b71Sopenharmony_ci    hilog.info(0x0000, 'testTag', 'StartupTask_001 onDependencyCompleted, dependence: %{public}s, result: %{public}s',
211e41f4b71Sopenharmony_ci      dependence, JSON.stringify(result));
212e41f4b71Sopenharmony_ci  }
213e41f4b71Sopenharmony_ci}
214e41f4b71Sopenharmony_ci```
215e41f4b71Sopenharmony_ci
216e41f4b71Sopenharmony_ci### (Optional) Changing the Startup Mode
217e41f4b71Sopenharmony_ci
218e41f4b71Sopenharmony_ciAppStartup provides automatic and manual mode. By default, the automatic mode is used. However, you can change the mode to manual as required.
219e41f4b71Sopenharmony_ci
220e41f4b71Sopenharmony_ci- Automatic mode: After an AbilityStage is created, the startup task is automatically executed.
221e41f4b71Sopenharmony_ci- Manual mode: After a UIAbility is created, you need to manually call the API to execute the startup task. Modules that are infrequently used do not need to be initialized when the application is started. You can change the startup mode of these modules to manual. After the application is started, you can call [startupManager.run](../reference/apis-ability-kit/js-apis-app-appstartup-startupManager.md#startupmanagerrun) to execute the startup task.
222e41f4b71Sopenharmony_ci
223e41f4b71Sopenharmony_ciThe following uses the **onCreate** lifecycle of the UIAbility as an example to describe how to manually trigger a startup task. The sample code is as follows:
224e41f4b71Sopenharmony_ci
225e41f4b71Sopenharmony_ci```ts
226e41f4b71Sopenharmony_ciimport { AbilityConstant, UIAbility, Want, startupManager } from '@kit.AbilityKit';
227e41f4b71Sopenharmony_ciimport { hilog } from '@kit.PerformanceAnalysisKit';
228e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit';
229e41f4b71Sopenharmony_ci
230e41f4b71Sopenharmony_ciexport default class EntryAbility extends UIAbility {
231e41f4b71Sopenharmony_ci  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
232e41f4b71Sopenharmony_ci    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
233e41f4b71Sopenharmony_ci    let startParams = ['StartupTask_005', 'StartupTask_006'];
234e41f4b71Sopenharmony_ci    try {
235e41f4b71Sopenharmony_ci      startupManager.run(startParams).then(() => {
236e41f4b71Sopenharmony_ci        console.log('StartupTest startupManager run then, startParams = ');
237e41f4b71Sopenharmony_ci      }).catch((error: BusinessError) => {
238e41f4b71Sopenharmony_ci        console.info("StartupTest promise catch error, error = " + JSON.stringify(error));
239e41f4b71Sopenharmony_ci        console.info("StartupTest promise catch error, startParams = "
240e41f4b71Sopenharmony_ci          + JSON.stringify(startParams));
241e41f4b71Sopenharmony_ci      })
242e41f4b71Sopenharmony_ci    } catch (error) {
243e41f4b71Sopenharmony_ci      let errMsg = JSON.stringify(error);
244e41f4b71Sopenharmony_ci      let errCode: number = error.code;
245e41f4b71Sopenharmony_ci      console.log('Startup catch error , errCode= ' + errCode);
246e41f4b71Sopenharmony_ci      console.log('Startup catch error ,error= ' + errMsg);
247e41f4b71Sopenharmony_ci    }
248e41f4b71Sopenharmony_ci  }
249e41f4b71Sopenharmony_ci
250e41f4b71Sopenharmony_ci  // ...
251e41f4b71Sopenharmony_ci}
252e41f4b71Sopenharmony_ci```
253e41f4b71Sopenharmony_ci
254e41f4b71Sopenharmony_ciYou can also call the API to trigger the manual mode after a page is loaded. The sample code is as follows:
255e41f4b71Sopenharmony_ci
256e41f4b71Sopenharmony_ci```ts
257e41f4b71Sopenharmony_ciimport { startupManager } from '@kit.AbilityKit';
258e41f4b71Sopenharmony_ci
259e41f4b71Sopenharmony_ci@Entry
260e41f4b71Sopenharmony_ci@Component
261e41f4b71Sopenharmony_cistruct Index {
262e41f4b71Sopenharmony_ci  @State message: string = 'Manual Mode'
263e41f4b71Sopenharmony_ci  @State startParams: Array<string> = ['StartupTask_006'];
264e41f4b71Sopenharmony_ci
265e41f4b71Sopenharmony_ci  build() {
266e41f4b71Sopenharmony_ci    RelativeContainer() {
267e41f4b71Sopenharmony_ci      Button(this.message)
268e41f4b71Sopenharmony_ci        .id('AppStartup')
269e41f4b71Sopenharmony_ci        .fontSize(20)
270e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
271e41f4b71Sopenharmony_ci        .onClick(() => {
272e41f4b71Sopenharmony_ci          if (!startupManager.isStartupTaskInitialized("StartupTask_006")) { // Check whether the startup task finishes execution.
273e41f4b71Sopenharmony_ci            startupManager.run(this.startParams)
274e41f4b71Sopenharmony_ci          }
275e41f4b71Sopenharmony_ci        })
276e41f4b71Sopenharmony_ci        .alignRules({
277e41f4b71Sopenharmony_ci          center: {anchor: '__container__', align: VerticalAlign.Center},
278e41f4b71Sopenharmony_ci          middle: {anchor: '__container__', align: HorizontalAlign.Center}
279e41f4b71Sopenharmony_ci        })
280e41f4b71Sopenharmony_ci    }
281e41f4b71Sopenharmony_ci    .height('100%')
282e41f4b71Sopenharmony_ci    .width('100%')
283e41f4b71Sopenharmony_ci  }
284e41f4b71Sopenharmony_ci}
285e41f4b71Sopenharmony_ci```
286e41f4b71Sopenharmony_ci
287