1# ArrayBuffer Object 2 3An ArrayBuffer object contains a block of native memory, and its JS object wrapper is allocated in the local heap of the virtual machine. Similar to a regular object, an ArrayBuffer object requires serialization and deserialization. However, the native memory can be passed in two ways: pass-by-copy and pass-by-transfer. 4 5When pass-by-copy is used, a deep copy (recursive traversal) is required, and both threads can independently access the ArrayBuffer object after the transmission. The following figure shows the communication process. 6 7 8 9If pass-by-transfer is used, the original thread can no longer use the ArrayBuffer object. During inter-thread communication, only the JS shell needs to be reconstructed, and the native memory does not need to be copied, resulting in higher efficiency. The following figure shows the communication process. 10 11 12 13ArrayBuffer objects can be used to represent resources such as images. In application development, scenarios requiring image processing (such as adjusting an image's brightness, saturation, or size) are common. To avoid blocking the UI main thread, images can be passed to child threads to perform these operations. Pass-by-transfer is more performant, but the original thread can no longer access the ArrayBuffer object. If both threads need access, pass-by-copy should be used; otherwise, pass-by-transfer is recommended to enhance performance. 14 15The following describes how to pass an image to a child thread using both methods. 16 17## Pass-by-Copy 18 19In ArkTS, TaskPool defaults to passing ArrayBuffer data by transfer. By calling the **setTransferList()** interface, you can specify which parts of the data should be passed by transfer, while the rest can be switched to pass-by-copy. 20 21First, implement an interface for processing the ArrayBuffer that will be executed in the Task. 22 23Then, pass the ArrayBuffer data to the Task by copy and process it within the Task. 24 25Finally, the UI main thread receives the ArrayBuffer data returned after the Task execution and concatenates the data for display. 26 27```ts 28// Index.ets 29import { taskpool } from '@kit.ArkTS'; 30import { BusinessError } from '@kit.BasicServicesKit'; 31 32@Concurrent 33function adjustImageValue(arrayBuffer: ArrayBuffer): ArrayBuffer { 34 // Perform operations on the ArrayBuffer. 35 return arrayBuffer; // The return value is passed by transfer by default. 36} 37 38function createImageTask(arrayBuffer: ArrayBuffer, isParamsByTransfer: boolean): taskpool.Task { 39 let task: taskpool.Task = new taskpool.Task(adjustImageValue, arrayBuffer); 40 if (!isParamsByTransfer) { // Whether to use pass-by-transfer. 41 // Pass an empty array [] to indicate that all ArrayBuffer parameters should be passed by copy. 42 task.setTransferList([]); 43 } 44 return task; 45} 46 47@Entry 48@Component 49struct Index { 50 @State message: string = 'Hello World'; 51 52 build() { 53 RelativeContainer() { 54 Text(this.message) 55 .id('HelloWorld') 56 .fontSize(50) 57 .fontWeight(FontWeight.Bold) 58 .alignRules({ 59 center: { anchor: '__container__', align: VerticalAlign.Center }, 60 middle: { anchor: '__container__', align: HorizontalAlign.Center } 61 }) 62 .onClick(() => { 63 let taskNum = 4; 64 let arrayBuffer = new ArrayBuffer(1024 * 1024); 65 let taskPoolGroup = new taskpool.TaskGroup(); 66 // Create taskNum tasks. 67 for (let i: number = 0; i < taskNum; i++) { 68 let arrayBufferSlice: ArrayBuffer = arrayBuffer.slice(arrayBuffer.byteLength / taskNum * i, arrayBuffer.byteLength / taskNum * (i + 1)); 69 // To pass the ArrayBuffer object by copy, set isParamsByTransfer to false. 70 taskPoolGroup.addTask(createImageTask(arrayBufferSlice, false)); 71 } 72 // Execute the tasks. 73 taskpool.execute(taskPoolGroup).then((data) => { 74 // Concatenate the results to obtain the final result. 75 }).catch((e: BusinessError) => { 76 console.error(e.message); 77 }) 78 }) 79 } 80 .height('100%') 81 .width('100%') 82 } 83} 84``` 85 86## Pass-by-Transfer 87 88TaskPool defaults to passing ArrayBuffer data by transfer, and the original thread can no longer use the ArrayBuffer passed to the child thread. To achieve this, simply remove the **task.setTransferList** interface call in the preceding code, meaning the second parameter of **createImageTask** should be **true**. 89