1# 通过标准化数据通路实现数据共享 (ArkTS) 2<!--Kit: ArkData--> 3<!--Subsystem: DistributedDataManager--> 4<!--Owner: @jcwen--> 5<!--Designer: @junathuawei1; @zph000--> 6<!--Tester: @lj_liujing; @yippo; @logic42--> 7<!--Adviser: @ge-yafang--> 8 9 10## 场景介绍 11 12在多对多跨应用数据共享的场景下,需要提供一条数据通路能够写入多个不同应用的数据并共享给其他应用进行读取。 13 14UDMF针对多对多跨应用数据共享的不同业务场景提供了标准化的数据通路,提供了标准化的数据写入与读取接口。 15 16## 标准化数据通路的定义和实现 17 18标准化数据通路是为各种业务场景提供的跨应用的数据写入与读取通路,它可以暂存应用需要共享的符合标准化数据定义的统一数据对象,并提供给其他应用进行访问,同时按照一定的策略对暂存数据的修改、删除权限和生命周期进行管理。 19 20标准化数据通路通过UDMF提供的系统服务实现,应用(数据提供方)需要共享公共数据时可以通过UDMF提供的插入接口将数据写入到UDMF的数据通路中,并且可以通过UDMF提供的更新和删除接口对本应用已经存入数据进行更新和删除操作。目标应用(数据访问方)可以通过UDMF提供的读取接口进行数据的访问。 21 22标准化数据通路相关接口不推荐多线程调用。 23 24统一数据对象UnifiedData在UDMF数据通路中具有全局唯一URI标识,其定义为udmf://intention/bundleName/groupId,其中各组成部分的含义分别为: 25 26+ **udmf:** 协议名,表示使用UDMF提供的数据通路。 27 28+ **intention:** UDMF已经支持的数据通路类型枚举值,对应不同的业务场景。 29 30+ **bundleName:** 数据来源应用的包名称。 31 32+ **groupId:** 分组名称,支持批量数据分组管理。 33 34当前UDMF中的跨应用数据共享通路有:**公共数据通路** 35 36**公共数据通路**:应用共享的公用数据共享通路,所有应用均可向通路中写入数据,写入方可以根据写入数据时生成的数据唯一标识符进行数据的更新、删除、指定数据标识符进行查询、全量查询;数据读取方能通过唯一标识符读取指定的数据,也可以设置Intention枚举类型为DATA_HUB来读取当前数据通路中的全量数据。公共数据通路通常仅用于传输应用间的过程数据,无法用于传输沙箱目录下文件等有权限管控的数据。UDMF会统一对数据的生命周期进行管理,每小时定期清理存入时长超过一小时的数据。 37 38## 接口说明 39 40以下是UDMF标准化数据通路的相关接口,均为异步接口。异步接口均有callback和Promise两种返回形式,下表均以callback形式为例,更多接口及使用方式请见[标准化数据通路](../reference/apis-arkdata/js-apis-data-unifiedDataChannel.md)和[标准化数据定义与描述](../reference/apis-arkdata/js-apis-data-uniformTypeDescriptor.md)。 41 42| 接口名称 | 描述 | 43|-----------------------------------------------------------------------------------------|---------------------------------------------| 44| insertData(options: Options, data: UnifiedData, callback: AsyncCallback\<string>): void | 将数据写入UDMF的公共数据通路中,并生成数据的唯一标识符,使用callback异步回调。 | 45| updateData(options: Options, data: UnifiedData, callback: AsyncCallback\<void>): void | 更新已写入UDMF的公共数据通路的数据,使用callback异步回调。 | 46| queryData(options: Options, callback: AsyncCallback\<Array\<UnifiedData>>): void | 查询UDMF公共数据通路的数据,使用callback异步回调。 | 47| deleteData(options: Options, callback: AsyncCallback\<Array\<UnifiedData>>): void | 删除UDMF公共数据通路的数据,返回删除的数据集,使用callback异步回调。 | 48 49 50## 开发步骤 51 52以[PlainText](../reference/apis-arkdata/js-apis-data-uniformDataStruct.md#plaintext)、[HTML](../reference/apis-arkdata/js-apis-data-uniformDataStruct.md#html)、[PixelMap](../reference/apis-arkdata/js-apis-data-uniformDataStruct.md#pixelmap15)三种数据进行多对多数据共享的过程为例说明开发步骤,数据提供方可以通过UMDF提供的insertData接口将数据写入公共数据通路,获取到的返回值(生成的数据的唯一标识符),可用于对其插入的数据进行更新和删除操作。数据访问方则可以通过UDMF提供的查询接口获取当前公共数据通路的全量数据。 53 54### 数据提供方 55 561. 导入unifiedDataChannel、uniformTypeDescriptor和uniformDataStruct模块。 57 58 ```ts 59 import { unifiedDataChannel, uniformTypeDescriptor, uniformDataStruct } from '@kit.ArkData'; 60 ``` 612. 创建一个统一数据对象并插入到UDMF的公共数据通路中。 62 63 ```ts 64 import { BusinessError } from '@kit.BasicServicesKit'; 65 import { image } from '@kit.ImageKit'; 66 // 准备PlainText文本数据内容 67 let plainTextObj : uniformDataStruct.PlainText = { 68 uniformDataType: 'general.plain-text', 69 textContent : 'Hello world', 70 abstract : 'This is abstract' 71 } 72 let record = new unifiedDataChannel.UnifiedRecord(uniformTypeDescriptor.UniformDataType.PLAIN_TEXT, plainTextObj); 73 // 准备HTML数据内容 74 let htmlObj : uniformDataStruct.HTML = { 75 uniformDataType :'general.html', 76 htmlContent : '<div><p>Hello world</p></div>', 77 plainContent : 'Hello world' 78 } 79 // 为该记录增加一种样式,两种样式存储的是同一个数据,为不同表达形式 80 record.addEntry(uniformTypeDescriptor.UniformDataType.HTML, htmlObj); 81 let unifiedData = new unifiedDataChannel.UnifiedData(record); 82 83 // 准备pixelMap数据内容 84 let arrayBuffer = new ArrayBuffer(4*3*3); 85 let opt : image.InitializationOptions = { editable: true, pixelFormat: 3, size: { height: 3, width: 3 }, alphaType: 3 }; 86 let pixelMap : uniformDataStruct.PixelMap = { 87 uniformDataType : 'openharmony.pixel-map', 88 pixelMap : image.createPixelMapSync(arrayBuffer, opt) 89 } 90 unifiedData.addRecord(new unifiedDataChannel.UnifiedRecord(uniformTypeDescriptor.UniformDataType.OPENHARMONY_PIXEL_MAP, pixelMap)); 91 // 指定要插入数据的数据通路枚举类型 92 let options: unifiedDataChannel.Options = { 93 intention: unifiedDataChannel.Intention.DATA_HUB 94 } 95 try { 96 unifiedDataChannel.insertData(options, unifiedData, (err, key) => { 97 if (err === undefined) { 98 console.info(`Succeeded in inserting data. key = ${key}`); 99 } else { 100 console.error(`Failed to insert data. code is ${err.code},message is ${err.message} `); 101 } 102 }); 103 } catch (e) { 104 let error: BusinessError = e as BusinessError; 105 console.error(`Insert data throws an exception. code is ${error.code},message is ${error.message} `); 106 } 107 ``` 1083. 更新上一步插入的统一数据对象。 109 110 ```ts 111 let plainTextUpdate : uniformDataStruct.PlainText = { 112 uniformDataType: 'general.plain-text', 113 textContent : 'How are you', 114 abstract : 'This is abstract' 115 } 116 let recordUpdate = new unifiedDataChannel.UnifiedRecord(uniformTypeDescriptor.UniformDataType.PLAIN_TEXT, plainTextUpdate); 117 let htmlUpdate : uniformDataStruct.HTML = { 118 uniformDataType :'general.html', 119 htmlContent : '<div><p>How are you</p></div>', 120 plainContent : 'How are you' 121 } 122 recordUpdate.addEntry(uniformTypeDescriptor.UniformDataType.HTML, htmlUpdate); 123 let unifiedDataUpdate = new unifiedDataChannel.UnifiedData(recordUpdate); 124 125 // 指定要更新的统一数据对象的URI 126 let optionsUpdate: unifiedDataChannel.Options = { 127 // 此处的key值仅为示例,不可直接使用,其值与insertData接口回调函数中key保持一致 128 key: 'udmf://DataHub/com.ohos.test/0123456789' 129 }; 130 131 try { 132 unifiedDataChannel.updateData(optionsUpdate, unifiedDataUpdate, (err) => { 133 if (err === undefined) { 134 console.info('Succeeded in updating data.'); 135 } else { 136 console.error(`Failed to update data. code is ${err.code},message is ${err.message} `); 137 } 138 }); 139 } catch (e) { 140 let error: BusinessError = e as BusinessError; 141 console.error(`Update data throws an exception. code is ${error.code},message is ${error.message} `); 142 } 143 ``` 1444. 删除存储在UDMF公共数据通路中的统一数据对象。 145 146 ```ts 147 // 指定要删除数据的数据通路枚举类型 148 let optionsDelete: unifiedDataChannel.Options = { 149 intention: unifiedDataChannel.Intention.DATA_HUB 150 }; 151 152 try { 153 unifiedDataChannel.deleteData(optionsDelete, (err, data) => { 154 if (err === undefined) { 155 console.info(`Succeeded in deleting data. size = ${data.length}`); 156 for (let i = 0; i < data.length; i++) { 157 let records = data[i].getRecords(); 158 for (let j = 0; j < records.length; j++) { 159 let types = records[j].getTypes(); 160 // 根据业务需要从记录中获取样式数据 161 if (types.includes(uniformTypeDescriptor.UniformDataType.PLAIN_TEXT)) { 162 let text = records[j].getEntry(uniformTypeDescriptor.UniformDataType.PLAIN_TEXT) as uniformDataStruct.PlainText; 163 console.info(`${i + 1}.${text.textContent}`); 164 } 165 if (types.includes(uniformTypeDescriptor.UniformDataType.HTML)) { 166 let html = records[j].getEntry(uniformTypeDescriptor.UniformDataType.HTML) as uniformDataStruct.HTML; 167 console.info(`${i + 1}.${html.htmlContent}`); 168 } 169 } 170 } 171 } else { 172 console.error(`Failed to delete data. code is ${err.code},message is ${err.message} `); 173 } 174 }); 175 } catch (e) { 176 let error: BusinessError = e as BusinessError; 177 console.error(`Delete data throws an exception. code is ${error.code},message is ${error.message} `); 178 } 179 ``` 180 181### 数据访问方 182 1831. 导入unifiedDataChannel、uniformTypeDescriptor和uniformDataStruct模块。 184 185 ```ts 186 import { unifiedDataChannel, uniformTypeDescriptor, uniformDataStruct } from '@kit.ArkData'; 187 ``` 1882. 查询存储在UDMF公共数据通路中的全量统一数据对象。 189 190 ```ts 191 import { BusinessError } from '@kit.BasicServicesKit'; 192 // 指定要查询数据的数据通路枚举类型 193 let options: unifiedDataChannel.Options = { 194 intention: unifiedDataChannel.Intention.DATA_HUB 195 }; 196 197 try { 198 unifiedDataChannel.queryData(options, (err, data) => { 199 if (err === undefined) { 200 console.info(`Succeeded in querying data. size = ${data.length}`); 201 for (let i = 0; i < data.length; i++) { 202 let records = data[i].getRecords(); 203 for (let j = 0; j < records.length; j++) { 204 let types = records[j].getTypes(); 205 // 根据业务需要从记录中获取样式数据 206 if (types.includes(uniformTypeDescriptor.UniformDataType.PLAIN_TEXT)) { 207 let text = records[j].getEntry(uniformTypeDescriptor.UniformDataType.PLAIN_TEXT) as uniformDataStruct.PlainText; 208 console.info(`${i + 1}.${text.textContent}`); 209 } 210 if (types.includes(uniformTypeDescriptor.UniformDataType.HTML)) { 211 let html = records[j].getEntry(uniformTypeDescriptor.UniformDataType.HTML) as uniformDataStruct.HTML; 212 console.info(`${i + 1}.${html.htmlContent}`); 213 } 214 } 215 } 216 } else { 217 console.error(`Failed to query data. code is ${err.code},message is ${err.message} `); 218 } 219 }); 220 } catch(e) { 221 let error: BusinessError = e as BusinessError; 222 console.error(`Query data throws an exception. code is ${error.code},message is ${error.message} `); 223 } 224 ``` 225