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. To address this, these modules should be loaded concurrently in separate background threads to reduce launch latency. 4 5By leveraging the TaskPool capabilities provided by ArkTS, different service initialization tasks can be offloaded to background 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 68 Define the timer service module as follows: 69 70 ```ts 71 // sdk/TimerSdk.ets 72 @Sendable 73 export class TimerSdk { 74 static init(): TimerSdk { 75 let timer = new TimerSdk() 76 return timer 77 } 78 79 async Countdown(time: number) { 80 return new Promise((resolve: (value: boolean) => void) => { 81 setTimeout(() => { 82 resolve(true) 83 }, time) 84 }) 85 } 86 } 87 ``` 88 892. 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: 90 91 ```ts 92 // Index.ets 93 import { Calculator } from '../sdk/Calculator' 94 import { TimerSdk } from '../sdk/TimerSdk' 95 import { taskpool } from '@kit.ArkTS'; 96 97 @Concurrent 98 function initCalculator(): Calculator { 99 return Calculator.init() 100 } 101 102 @Concurrent 103 function initTimerSdk(): TimerSdk { 104 return TimerSdk.init() 105 } 106 107 @Entry 108 @Component 109 struct Index { 110 calc?: Calculator 111 timer?: TimerSdk 112 113 aboutToAppear(): void { 114 taskpool.execute(initCalculator).then((ret) => { 115 this.calc = ret as Calculator 116 }) 117 taskpool.execute(initTimerSdk).then((ret) => { 118 this.timer = ret as TimerSdk 119 }) 120 } 121 122 build() { 123 Row() { 124 Column() { 125 Text("calculate add") 126 .id('add') 127 .fontSize(50) 128 .fontWeight(FontWeight.Bold) 129 .alignRules({ 130 center: { anchor: '__container__', align: VerticalAlign.Center }, 131 middle: { anchor: '__container__', align: HorizontalAlign.Center } 132 }) 133 .onClick(async () => { 134 let result = this.calc?.add(1, 2) 135 console.info(`Result is ${result}`) 136 }) 137 Text("show history") 138 .id('show') 139 .fontSize(50) 140 .fontWeight(FontWeight.Bold) 141 .alignRules({ 142 center: { anchor: '__container__', align: VerticalAlign.Center }, 143 middle: { anchor: '__container__', align: HorizontalAlign.Center } 144 }) 145 .onClick(async () => { 146 this.calc?.showHistory() 147 }) 148 Text("countdown") 149 .id('get') 150 .fontSize(50) 151 .fontWeight(FontWeight.Bold) 152 .alignRules({ 153 center: { anchor: '__container__', align: VerticalAlign.Center }, 154 middle: { anchor: '__container__', align: HorizontalAlign.Center } 155 }) 156 .onClick(async () => { 157 console.info(`Timer start`) 158 await this.timer?.Countdown(1000); 159 console.info(`Timer end`) 160 }) 161 } 162 .width('100%') 163 } 164 .height('100%') 165 } 166 } 167 ``` 168