1# Transferable对象(NativeBinding对象) 2 3 4Transferable对象,也称为NativeBinding对象,是指绑定C++对象的JS对象,主体功能由C++提供,其JS对象壳被分配在虚拟机本地堆(LocalHeap)。跨线程传输时复用同一个C++对象,相比于JS对象的拷贝模式,传输效率高。因此,可共享或转移的NativeBinding对象也被称为Transferable对象。 5 6 7## 共享模式 8 9如果C++实现能够保证线程安全性,则这个NativeBinding对象的C++部分支持共享传输。此时,NativeBinding对象跨线程传输后,只需要重新创建JS壳,就可以桥接到相同的C++对象上。通信过程如下图所示: 10 11 12 13 14 15常见的共享模式NativeBinding对象包括Context对象,它包含应用程序组件的上下文信息,提供访问系统服务和资源的方式,使得应用程序组件可以与系统进行交互。获取Context信息的方法可以参考[获取上下文信息](../application-models/application-context-stage.md)。 16 17示例可参考[使用TaskPool进行频繁数据库操作](batch-database-operations-guide.md#使用taskpool进行频繁数据库操作)。 18 19 20## 转移模式 21 22如果C++实现包含数据,且无法保证线程安全性,则NativeBinding对象的C++部分需要采用转移方式传输。NativeBinding对象跨线程传输后,重新创建JS壳即可桥接到C++对象上,但需移除原对象的绑定关系。通信过程如下图所示: 23 24 25 26常见的转移模式NativeBinding对象包括[PixelMap对象](../reference/apis-image-kit/js-apis-image.md#imagecreatepixelmap8),它可以读取或写入图像数据,获取图像信息,常用于显示图片。 27 28### 使用示例 29 30这里提供了一个跨线程传递PixelMap对象的示例以帮助更好理解。首先获取rawfile文件夹中的图片资源,然后在子线程中创建PixelMap对象传递给主线程,具体实现如下: 31 32```ts 33// Index.ets 34import { taskpool } from '@kit.ArkTS'; 35import { loadPixelMap } from './pixelMapTest'; 36import { BusinessError } from '@kit.BasicServicesKit'; 37 38@Entry 39@Component 40struct Index { 41 @State message: string = 'Hello World'; 42 @State pixelMap: PixelMap | undefined = undefined; 43 44 private loadImageFromThread(): void { 45 let context : Context = this.getUIContext().getHostContext() as Context; 46 const resourceMgr = context.resourceManager; 47 // 此处‘startIcon.png’为media下复制到rawfile文件夹中,请开发者自行替换,否则imageSource创建失败会导致后续无法正常执行。 48 resourceMgr.getRawFd('startIcon.png').then(rawFileDescriptor => { 49 taskpool.execute(loadPixelMap, rawFileDescriptor).then(pixelMap => { 50 if (pixelMap) { 51 this.pixelMap = pixelMap as PixelMap; 52 console.log('Succeeded in creating pixelMap.'); 53 // 主线程释放pixelMap。由于子线程返回pixelMap时已调用setTransferDetached,所以此处能够立即释放pixelMap。 54 this.pixelMap.release(); 55 } else { 56 console.error('Failed to create pixelMap.'); 57 } 58 }).catch((e: BusinessError) => { 59 console.error('taskpool execute loadPixelMap failed. Code: ' + e.code + ', message: ' + e.message); 60 }); 61 }); 62 } 63 64 build() { 65 RelativeContainer() { 66 Text(this.message) 67 .id('HelloWorld') 68 .fontSize(50) 69 .fontWeight(FontWeight.Bold) 70 .alignRules({ 71 center: { anchor: 'container', align: VerticalAlign.Center }, 72 middle: { anchor: 'container', align: HorizontalAlign.Center } 73 }) 74 .onClick(() => { 75 this.loadImageFromThread(); 76 }) 77 } 78 .height('100%') 79 .width('100%') 80 } 81} 82``` 83 84```ts 85// pixelMapTest.ets 86import { image } from '@kit.ImageKit'; 87 88@Concurrent 89export async function loadPixelMap(rawFileDescriptor: number): Promise<PixelMap> { 90 // 创建imageSource。 91 const imageSource = image.createImageSource(rawFileDescriptor); 92 // 创建pixelMap。 93 const pixelMap = imageSource.createPixelMapSync(); 94 // 释放imageSource。 95 imageSource.release(); 96 // 使pixelMap在跨线程传输完成后,断开原线程的引用。 97 pixelMap.setTransferDetached(true); 98 // 返回pixelMap给主线程。 99 return pixelMap; 100} 101``` 102