1# Sendable使用场景 2<!--Kit: ArkTS--> 3<!--Subsystem: CommonLibrary--> 4<!--Owner: @lijiamin2025--> 5<!--Designer: @weng-changcheng--> 6<!--Tester: @kirl75; @zsw_zhushiwei--> 7<!--Adviser: @ge-yafang--> 8Sendable对象在不同并发实例间默认采用引用传递,这种方式比序列化更高效,且不会丢失类成员方法。因此,Sendable能够解决两个关键场景的问题: 9 10- 跨并发实例传输大数据(例如达到100KB以上的数据)。 11 12- 跨并发实例传递带方法的class实例对象。 13 14## 跨并发实例传输大数据场景 15 16由于跨并发实例序列化的开销随数据量线性增长,因此当传输数据量较大时(100KB的数据传输耗时约为1ms),跨并发实例的拷贝开销会影响应用性能。使用引用传递方式传输对象可提升性能。 17 18**示例:** 19 20```ts 21// Index.ets 22import { taskpool } from '@kit.ArkTS'; 23import { testTypeA, testTypeB, Test } from './sendable'; 24import { BusinessError, emitter } from '@kit.BasicServicesKit'; 25 26// 在并发函数中模拟数据处理 27@Concurrent 28async function taskFunc(obj: Test) { 29 console.info("test task res1 is: " + obj.data1.name + " res2 is: " + obj.data2.name); 30} 31 32async function test() { 33 // 使用taskpool传递数据 34 let a: testTypeA = new testTypeA("testTypeA"); 35 let b: testTypeB = new testTypeB("testTypeB"); 36 let obj: Test = new Test(a, b); 37 let task: taskpool.Task = new taskpool.Task(taskFunc, obj); 38 await taskpool.execute(task); 39} 40 41@Concurrent 42function SensorListener() { 43 // 监听逻辑 44 // ... 45} 46 47@Entry 48@Component 49struct Index { 50 build() { 51 Column() { 52 Text("Listener task") 53 .id('HelloWorld') 54 .fontSize(50) 55 .fontWeight(FontWeight.Bold) 56 .onClick(() => { 57 let sensorTask = new taskpool.LongTask(SensorListener); 58 emitter.on({ eventId: 0 }, (data) => { 59 // Do something here 60 console.info(`Receive ACCELEROMETER data: {${data.data?.x}, ${data.data?.y}, ${data.data?.z}}`); 61 }); 62 taskpool.execute(sensorTask).then(() => { 63 console.info("Add listener of ACCELEROMETER success"); 64 }).catch((e: BusinessError) => { 65 // Process error 66 }) 67 }) 68 Text("Data processing task") 69 .id('HelloWorld') 70 .fontSize(50) 71 .fontWeight(FontWeight.Bold) 72 .onClick(() => { 73 test(); 74 }) 75 } 76 .height('100%') 77 .width('100%') 78 } 79} 80``` 81<!-- @[across_concurrent_instance_transfer_large_data ](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/SendableScenarios/bigdata/src/main/ets/pages/Index.ets) --> 82 83```ts 84// sendable.ets 85// 将数据量较大的数据在Sendable class中组装 86@Sendable 87export class testTypeA { 88 name: string = "A"; 89 constructor(name: string) { 90 this.name = name; 91 } 92} 93 94@Sendable 95export class testTypeB { 96 name: string = "B"; 97 constructor(name: string) { 98 this.name = name; 99 } 100} 101 102@Sendable 103export class Test { 104 data1: testTypeA; 105 data2: testTypeB; 106 constructor(arg1: testTypeA, arg2: testTypeB) { 107 this.data1 = arg1; 108 this.data2 = arg2; 109 } 110} 111``` 112<!-- @[across_concurrent_instance_transfer_large_data ](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/SendableScenarios/bigdata/src/main/ets/pages/sendable.ets) --> 113 114 115## 跨并发实例传递带方法的class实例对象 116 117在序列化传输实例对象时,会丢失方法。因此,若需调用实例方法,应使用引用传递。处理数据时,若需解析数据,可使用[ASON工具](ason-parsing-generation.md)。 118 119**示例:** 120 121```ts 122// Index.ets 123import { taskpool, ArkTSUtils } from '@kit.ArkTS'; 124import { SendableTestClass, ISendable } from './sendable'; 125 126// 在并发函数中模拟数据处理 127@Concurrent 128async function taskFunc(sendableObj: SendableTestClass) { 129 console.info("SendableTestClass: name is: " + sendableObj.printName() + ", age is: " + sendableObj.printAge() + ", sex is: " + sendableObj.printSex()); 130 sendableObj.setAge(28); 131 console.info("SendableTestClass: age is: " + sendableObj.printAge()); 132 133 // 解析sendableObj.arr数据生成JSON字符串 134 let str = ArkTSUtils.ASON.stringify(sendableObj.arr); 135 console.info("SendableTestClass: str is: " + str); 136 137 // 解析该数据并生成ISendable数据 138 let jsonStr = '{"name": "Alexa", "age": 23, "sex": "female"}'; 139 let obj = ArkTSUtils.ASON.parse(jsonStr) as ISendable; 140 console.info("SendableTestClass: type is: " + typeof obj); 141 console.info("SendableTestClass: name is: " + (obj as object)?.["name"]); // 输出: 'Alexa' 142 console.info("SendableTestClass: age is: " + (obj as object)?.["age"]); // 输出: 23 143 console.info("SendableTestClass: sex is: " + (obj as object)?.["sex"]); // 输出: 'female' 144} 145async function test() { 146 // 使用taskpool传递数据 147 let obj: SendableTestClass = new SendableTestClass(); 148 let task: taskpool.Task = new taskpool.Task(taskFunc, obj); 149 await taskpool.execute(task); 150} 151 152@Entry 153@Component 154struct Index { 155 @State message: string = 'Hello World'; 156 157 build() { 158 RelativeContainer() { 159 Text(this.message) 160 .id('HelloWorld') 161 .fontSize(50) 162 .fontWeight(FontWeight.Bold) 163 .alignRules({ 164 center: { anchor: '__container__', align: VerticalAlign.Center }, 165 middle: { anchor: '__container__', align: HorizontalAlign.Center } 166 }) 167 .onClick(() => { 168 test(); 169 }) 170 } 171 .height('100%') 172 .width('100%') 173 } 174} 175``` 176<!-- @[across_concurrent_instance_pass_class_method](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/SendableScenarios/crossconcurrency/src/main/ets/pages/Index.ets) --> 177 178```ts 179// sendable.ets 180// 定义模拟类SendableTestClass,模仿开发过程中需传递带方法的class 181import { lang, collections } from '@kit.ArkTS' 182 183export type ISendable = lang.ISendable; 184 185@Sendable 186export class SendableTestClass { 187 name: string = 'John'; 188 age: number = 20; 189 sex: string = "man"; 190 arr: collections.Array<number> = new collections.Array<number>(1, 2, 3); 191 constructor() { 192 } 193 setAge(age: number) : void { 194 this.age = age; 195 } 196 197 printName(): string { 198 return this.name; 199 } 200 201 printAge(): number { 202 return this.age; 203 } 204 205 printSex(): string { 206 return this.sex; 207 } 208} 209``` 210<!-- @[across_concurrent_instance_pass_class_method](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/SendableScenarios/crossconcurrency/src/main/ets/pages/sendable.ets) -->