1# 业务模块并发加载场景 2 3在应用启动过程中,会有多个业务模块需要加载,例如地图类应用的定位、打车、导航等不同的模块,如果全部在UI主线程初始化,则会严重影响冷启动耗时。此时需要在不同子线程并行化加载这些模块功能,降低启动耗时。 4 5通过使用ArkTS提供的TaskPool能力,可以将不同业务初始化任务移到子线程中,业务模块通过下沉C++实现成[NativeBinding对象](transferabled-object.md)、或者在ArkTS层定义[Sendable对象](arkts-sendable.md),就可以将初始化的模块返回UI主线程调用,实现如下。 6 71. 各业务功能(SDK)模块定义(这里以Sendable对象为例)。 8 计算器业务模块定义如下: 9 10 ```ts 11 // sdk/Calculator.ets 12 import { collections } from '@kit.ArkTS' 13 14 @Sendable 15 export class Calculator { 16 history?: collections.Array<collections.Array<string>> 17 totalCount: number = 0 18 19 static init(): Calculator { 20 let calc = new Calculator() 21 calc.totalCount = 0 22 calc.history = collections.Array.create(calc.totalCount, collections.Array.create(2, "")); 23 return calc 24 } 25 26 add(a: number, b: number) { 27 let result = a + b; 28 this.newCalc(`${a} + ${b}`, `${result}`); 29 return result 30 } 31 32 sub(a: number, b: number) { 33 let result = a - b; 34 this.newCalc(`${a} - ${b}`, `${result}`); 35 return result 36 } 37 38 mul(a: number, b: number) { 39 let result = a * b; 40 this.newCalc(`${a} * ${b}`, `${result}`); 41 return result 42 } 43 44 div(a: number, b: number) { 45 let result = a / b; 46 this.newCalc(`${a} / ${b}`, `${result}`); 47 return result 48 } 49 50 getHistory(): collections.Array<collections.Array<string>> { 51 return this.history!; 52 } 53 54 showHistory() { 55 for (let i = 0; i < this.totalCount; i++) { 56 console.info(`${i}: ${this.history![i][0]} = ${this.history![i][1]}`) 57 } 58 } 59 60 private newCalc(opt: string, ret: string) { 61 let newRecord = new collections.Array<string>(opt, ret) 62 this.totalCount = this.history!.unshift(newRecord) 63 } 64 } 65 ``` 66 67 定时器业务模块定义如下: 68 69 ```ts 70 // sdk/TimerSdk.ets 71 @Sendable 72 export class TimerSdk { 73 static init(): TimerSdk { 74 let timer = new TimerSdk() 75 return timer 76 } 77 78 async Countdown(time: number) { 79 return new Promise((resolve: (value: boolean) => void) => { 80 setTimeout(() => { 81 resolve(true) 82 }, time) 83 }) 84 } 85 } 86 ``` 87 882. 在UI主线程触发各业务模块分发到子线程,加载完成后在UI主线程使用。 89 90 ```ts 91 // Index.ets 92 import { Calculator } from '../sdk/Calculator' 93 import { TimerSdk } from '../sdk/TimerSdk' 94 import { taskpool } from '@kit.ArkTS'; 95 96 @Concurrent 97 function initCalculator(): Calculator { 98 return Calculator.init() 99 } 100 101 @Concurrent 102 function initTimerSdk(): TimerSdk { 103 return TimerSdk.init() 104 } 105 106 @Entry 107 @Component 108 struct Index { 109 calc?: Calculator 110 timer?: TimerSdk 111 112 aboutToAppear(): void { 113 taskpool.execute(initCalculator).then((ret) => { 114 this.calc = ret as Calculator 115 }) 116 taskpool.execute(initTimerSdk).then((ret) => { 117 this.timer = ret as TimerSdk 118 }) 119 } 120 121 build() { 122 Row() { 123 Column() { 124 Text("calculate add") 125 .id('add') 126 .fontSize(50) 127 .fontWeight(FontWeight.Bold) 128 .alignRules({ 129 center: { anchor: '__container__', align: VerticalAlign.Center }, 130 middle: { anchor: '__container__', align: HorizontalAlign.Center } 131 }) 132 .onClick(async () => { 133 let result = this.calc?.add(1, 2) 134 console.info(`Result is ${result}`) 135 }) 136 Text("show history") 137 .id('show') 138 .fontSize(50) 139 .fontWeight(FontWeight.Bold) 140 .alignRules({ 141 center: { anchor: '__container__', align: VerticalAlign.Center }, 142 middle: { anchor: '__container__', align: HorizontalAlign.Center } 143 }) 144 .onClick(async () => { 145 this.calc?.showHistory() 146 }) 147 Text("countdown") 148 .id('get') 149 .fontSize(50) 150 .fontWeight(FontWeight.Bold) 151 .alignRules({ 152 center: { anchor: '__container__', align: VerticalAlign.Center }, 153 middle: { anchor: '__container__', align: HorizontalAlign.Center } 154 }) 155 .onClick(async () => { 156 console.info(`Timer start`) 157 await this.timer?.Countdown(1000); 158 console.info(`Timer end`) 159 }) 160 } 161 .width('100%') 162 } 163 .height('100%') 164 } 165 } 166 ``` 167