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