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