• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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) -->