• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Concurrent Loading of Service Modules
2
3During application launch, multiple service modules need to be loaded. For example, in a mapping application, different modules such as positioning, ride-hailing, and navigation are required. Initializing all these modules in the UI main thread can significantly increase the cold start time of the application. To address this, these modules should be loaded concurrently in separate child threads to reduce launch latency.
4
5By leveraging the TaskPool capabilities provided by ArkTS, different service initialization tasks can be offloaded to child threads. Service modules can be implemented in C++ as [NativeBinding objects](transferabled-object.md) or defined in ArkTS as [Sendable objects](arkts-sendable.md). The initialized modules can then be returned to the UI main thread for use. The implementation involves the following steps:
6
71. Define each service module (SDK) (using Sendable objects as an example).
8
9   Define the calculator service module as follows:
10
11   ```ts
12   // sdk/Calculator.ets
13   import { collections } from '@kit.ArkTS'
14
15   @Sendable
16   export class Calculator {
17     history?: collections.Array<collections.Array<string>>
18     totalCount: number = 0
19
20     static init(): Calculator {
21       let calc = new Calculator()
22       calc.totalCount = 0
23       calc.history = collections.Array.create(calc.totalCount, collections.Array.create(2, ""));
24       return calc
25     }
26
27     add(a: number, b: number) {
28       let result = a + b;
29       this.newCalc(`${a} + ${b}`, `${result}`);
30       return result
31     }
32
33     sub(a: number, b: number) {
34       let result = a - b;
35       this.newCalc(`${a} - ${b}`, `${result}`);
36       return result
37     }
38
39     mul(a: number, b: number) {
40       let result = a * b;
41       this.newCalc(`${a} * ${b}`, `${result}`);
42       return result
43     }
44
45     div(a: number, b: number) {
46       let result = a / b;
47       this.newCalc(`${a} / ${b}`, `${result}`);
48       return result
49     }
50
51     getHistory(): collections.Array<collections.Array<string>> {
52       return this.history!;
53     }
54
55     showHistory() {
56       for (let i = 0; i < this.totalCount; i++) {
57         console.info(`${i}: ${this.history![i][0]} = ${this.history![i][1]}`)
58       }
59     }
60
61     private newCalc(opt: string, ret: string) {
62       let newRecord = new collections.Array<string>(opt, ret)
63       this.totalCount = this.history!.unshift(newRecord)
64     }
65   }
66   ```
67   <!-- @[define_calculator_module](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ApplicationMultithreadingDevelopment/PracticalCases/entry/src/main/ets/sdk/Calculator.ets) -->
68
69   Define the timer service module as follows:
70
71   ```ts
72   // sdk/TimerSdk.ets
73   @Sendable
74   export class TimerSdk {
75     static init(): TimerSdk {
76       let timer = new TimerSdk()
77       return timer
78     }
79
80     async Countdown(time: number) {
81       return new Promise((resolve: (value: boolean) => void) => {
82         setTimeout(() => {
83           resolve(true)
84         }, time)
85       })
86     }
87   }
88   ```
89   <!-- @[define_timer_module](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ApplicationMultithreadingDevelopment/PracticalCases/entry/src/main/ets/sdk/TimerSdk.ets) -->
90
912. In the UI main thread, trigger the distribution of service modules to child threads, and use them in the UI main thread after loading is complete. The following is an example:
92
93   ```ts
94   // Index.ets
95   import { Calculator } from '../sdk/Calculator'
96   import { TimerSdk } from '../sdk/TimerSdk'
97   import { taskpool } from '@kit.ArkTS';
98
99   @Concurrent
100   function initCalculator(): Calculator {
101     return Calculator.init()
102   }
103
104   @Concurrent
105   function initTimerSdk(): TimerSdk {
106     return TimerSdk.init()
107   }
108
109   @Entry
110   @Component
111   struct Index {
112     calc?: Calculator
113     timer?: TimerSdk
114
115     aboutToAppear(): void {
116       taskpool.execute(initCalculator).then((ret) => {
117         this.calc = ret as Calculator
118       })
119       taskpool.execute(initTimerSdk).then((ret) => {
120         this.timer = ret as TimerSdk
121       })
122     }
123
124     build() {
125       Row() {
126         Column() {
127           Text("calculate add")
128             .id('add')
129             .fontSize(50)
130             .fontWeight(FontWeight.Bold)
131             .alignRules({
132               center: { anchor: '__container__', align: VerticalAlign.Center },
133               middle: { anchor: '__container__', align: HorizontalAlign.Center }
134             })
135             .onClick(async () => {
136               let result = this.calc?.add(1, 2)
137               console.info(`Result is ${result}`)
138             })
139           Text("show history")
140             .id('show')
141             .fontSize(50)
142             .fontWeight(FontWeight.Bold)
143             .alignRules({
144               center: { anchor: '__container__', align: VerticalAlign.Center },
145               middle: { anchor: '__container__', align: HorizontalAlign.Center }
146             })
147             .onClick(async () => {
148               this.calc?.showHistory()
149             })
150           Text("countdown")
151             .id('get')
152             .fontSize(50)
153             .fontWeight(FontWeight.Bold)
154             .alignRules({
155               center: { anchor: '__container__', align: VerticalAlign.Center },
156               middle: { anchor: '__container__', align: HorizontalAlign.Center }
157             })
158             .onClick(async () => {
159               console.info(`Timer start`)
160               await this.timer?.Countdown(1000);
161               console.info(`Timer end`)
162             })
163         }
164         .width('100%')
165       }
166       .height('100%')
167     }
168   }
169   ```
170   <!-- @[distribute_child_thread](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ApplicationMultithreadingDevelopment/PracticalCases/entry/src/main/ets/managers/ConcurrentLoadingModulesGuide.ets) -->
171