• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 通过标准化数据通路实现数据共享 (C/C++)
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接口文档](../reference/apis-arkdata/capi-udmf-h.md)。
41
42| 接口名称                                                                                    | 描述                                          |
43|-----------------------------------------------------------------------------------------|---------------------------------------------|
44| OH_UdsHyperlink* OH_UdsHyperlink_Create()                                           | 创建超链接类型对象的指针。 |
45| int OH_UdsHyperlink_SetDescription(OH_UdsHyperlink* pThis, const char* description) | 设置超链接类型实例中的描述参数。 |
46| OH_UdmfRecord* OH_UdmfRecord_Create()                        | 创建一个指向统一数据记录OH_UdmfRecord的指针。               |
47| int OH_UdmfRecord_AddHyperlink(OH_UdmfRecord* pThis, OH_UdsHyperlink* hyperlink) | 向OH_UdmfRecord添加超链接类型数据。             |
48| OH_UdmfData* OH_UdmfData_Create()                            | 创建一个指向统一数据对象OH_UdmfData的指针。                 |
49| int OH_UdmfData_AddRecord(OH_UdmfData* pThis, OH_UdmfRecord* record) | 向OH_UdmfData中增加一条OH_UdmfRecord数据记录。      |
50| int OH_Udmf_SetUnifiedDataByOptions(OH_UdmfOptions* options, OH_UdmfData *unifiedData, char *key, unsigned int keyLen)        | 从统一数据管理框架数据库中写入统一数据对象OH_UdmfData数据。                          |
51| void OH_UdsHyperlink_Destroy(OH_UdsHyperlink* pThis)         | 销毁超链接类型指针指向的实例对象。 |
52| void OH_UdmfRecord_Destroy(OH_UdmfRecord* pThis)             | 销毁指向统一数据记录OH_UdmfRecord的指针。                   |
53| void OH_UdmfData_Destroy(OH_UdmfData* pThis)                 | 销毁指向统一数据对象OH_UdmfData的指针。                     |
54| char** OH_UdmfRecord_GetTypes(OH_UdmfRecord* pThis, unsigned int* count) | 获取OH_UdmfRecord中全部的数据类型。                     |
55| int OH_UdmfRecord_GetHyperlink(OH_UdmfRecord* pThis, OH_UdsHyperlink* hyperlink) | 获取OH_UdmfRecord中超链接类型数据。             |
56| int OH_Udmf_GetUnifiedDataByOptions(OH_UdmfOptions* options, OH_UdmfData** dataArray, unsigned int* dataSize) | 通过数据通路类型从统一数据管理框架数据库中获取统一数据对象数据。          |
57| int OH_Udmf_UpdateUnifiedData(OH_UdmfOptions* options, OH_UdmfData* unifiedData) | 对统一数据管理框架数据库中的统一数据对象数据进行数据更改。 |
58| int OH_Udmf_DeleteUnifiedData(OH_UdmfOptions* options, OH_UdmfData** dataArray, unsigned int* dataSize) | 删除统一数据管理框架数据库中的统一数据对象数据。|
59| bool OH_UdmfData_HasType(OH_UdmfData* pThis, const char* type) | 判断统一数据对象OH_UdmfData是否存在指定类型。               |
60| OH_UdmfRecord** OH_UdmfData_GetRecords(OH_UdmfData* pThis, unsigned int* count) | 获取OH_UdmfData中全部的数据记录。                           |
61| OH_UdmfRecordProvider* OH_UdmfRecordProvider_Create()        | 创建一个指向统一数据提供者的指针。                          |
62| int OH_UdmfRecordProvider_SetData(OH_UdmfRecordProvider* provider, void* context, const OH_UdmfRecordProvider_GetData callback, const UdmfData_Finalize finalize) | 设置统一数据提供者的回调函数。                              |
63| int OH_UdmfRecord_SetProvider(OH_UdmfRecord* pThis, const char* const* types, unsigned int count, OH_UdmfRecordProvider* provider) | 将统一数据提供者配置到OH_UdmfRecord中。    |
64| OH_UdmfOptions* OH_UdmfOptions_Create()        | 创建一个指向数据操作选项的指针。                          |
65| void OH_UdmfOptions_Destroy(OH_UdmfOptions* pThis)  | 销毁指向数据操作选项的指针。                          |
66
67
68## 添加动态链接库
69
70CMakeLists.txt中添加以下库。
71
72```txt
73libudmf.so, libhilog_ndk.z.so
74```
75
76## 引用头文件
77
78```c
79#include <cstdio>
80#include <cstring>
81#include <database/udmf/utd.h>
82#include <database/udmf/uds.h>
83#include <database/udmf/udmf.h>
84#include <database/udmf/udmf_meta.h>
85#include <database/udmf/udmf_err_code.h>
86#include <hilog/log.h>
87
88#undef LOG_TAG
89#define LOG_TAG "MY_LOG"
90```
91
92## 使用UDMF写入UDS数据
93
94下面以写入超链接OH_UdsHyperlink类型数据场景为例,说明如何使用UDS与UDMF。
951. 创建hyperlink的UDS数据结构。
962. 设置hyperlink中的URL和描述信息。
973. 创建OH_UdmfRecord对象,并向OH_UdmfRecord中添加超链接类型数据。
984. 创建OH_UdmfData对象,并向OH_UdmfData中添加OH_UdmfRecord。
995. 构建数据操作选项。
1006. 构建数据,将数据写入数据库中,得到返回的key值。
1017. 使用完成后销毁指针。
102
103```c
104void createDataTest()
105{
106    // 1. 创建hyperlink的UDS数据结构。
107    OH_UdsHyperlink* hyperlink = OH_UdsHyperlink_Create();
108    // 2. 设置hyperlink中的URL和描述信息。
109    if (OH_UdsHyperlink_SetUrl(hyperlink, "www.demo.com") != Udmf_ErrCode::UDMF_E_OK) {
110        OH_LOG_ERROR(LOG_APP, "Hyperlink set url error!");
111        OH_UdsHyperlink_Destroy(hyperlink);
112        return;
113    }
114    if (OH_UdsHyperlink_SetDescription(hyperlink, "This is the description.") != Udmf_ErrCode::UDMF_E_OK) {
115        OH_LOG_ERROR(LOG_APP, "Hyperlink set description error!");
116        OH_UdsHyperlink_Destroy(hyperlink);
117        return;
118    }
119    // 3. 创建OH_UdmfRecord对象,并向OH_UdmfRecord中添加超链接类型数据。
120    OH_UdmfRecord* record = OH_UdmfRecord_Create();
121    if (OH_UdmfRecord_AddHyperlink(record, hyperlink) != Udmf_ErrCode::UDMF_E_OK) {
122        OH_LOG_ERROR(LOG_APP, "Add hyperlink to record error!");
123        OH_UdsHyperlink_Destroy(hyperlink);
124        OH_UdmfRecord_Destroy(record);
125        return;
126    }
127    // 4. 创建OH_UdmfData对象,并向OH_UdmfData中添加OH_UdmfRecord。
128    OH_UdmfData* data = OH_UdmfData_Create();
129    if (OH_UdmfData_AddRecord(data, record) != Udmf_ErrCode::UDMF_E_OK) {
130        OH_LOG_ERROR(LOG_APP, "Add record to data error!");
131        OH_UdsHyperlink_Destroy(hyperlink);
132        OH_UdmfRecord_Destroy(record);
133        OH_UdmfData_Destroy(data);
134        return;
135    }
136    // 5. 构建数据操作选项。
137    OH_UdmfOptions* options = OH_UdmfOptions_Create();
138    if (OH_UdmfOptions_SetIntention(options, Udmf_Intention::UDMF_INTENTION_DATA_HUB) != Udmf_ErrCode::UDMF_E_OK) {
139        OH_LOG_ERROR(LOG_APP, "Set option error!");
140        OH_UdsHyperlink_Destroy(hyperlink);
141        OH_UdmfRecord_Destroy(record);
142        OH_UdmfData_Destroy(data);
143        OH_UdmfOptions_Destroy(options);
144        return;
145    }
146    // 6. 构建数据,将数据写入数据库中,得到返回的key值。
147    char key[UDMF_KEY_BUFFER_LEN] = {0};
148    if (OH_Udmf_SetUnifiedDataByOptions(options, data, key, sizeof(key)) != Udmf_ErrCode::UDMF_E_OK) {
149        OH_LOG_ERROR(LOG_APP, "Set data error!");
150        OH_UdsHyperlink_Destroy(hyperlink);
151        OH_UdmfRecord_Destroy(record);
152        OH_UdmfData_Destroy(data);
153        OH_UdmfOptions_Destroy(options);
154        return;
155    }
156    OH_LOG_INFO(LOG_APP, "key = %{public}s", key);
157    // 7. 使用完成后销毁指针。
158    OH_UdsHyperlink_Destroy(hyperlink);
159    OH_UdmfRecord_Destroy(record);
160    OH_UdmfData_Destroy(data);
161    OH_UdmfOptions_Destroy(options);
162}
163```
164
165## 使用UDMF获取UDS数据
166
167下面继续以获取超链接OH_UdsHyperlink类型数据场景为例,说明如何使用UDS与UDMF。
1681. 构建数据操作选项。
1692. 通过数据操作选项获取数据。
1703. 判断OH_UdmfData是否有对应的类型。
1714. 获取数据记录和hyperlink数据。
1725. 销毁指针。
173
174```c
175void getDataTest()
176{
177    // 1. 构建数据操作选项。
178    OH_UdmfOptions* options = OH_UdmfOptions_Create();
179    if (OH_UdmfOptions_SetIntention(options, Udmf_Intention::UDMF_INTENTION_DATA_HUB) != Udmf_ErrCode::UDMF_E_OK) {
180        OH_LOG_ERROR(LOG_APP, "Set option error!");
181        OH_UdmfOptions_Destroy(options);
182        return;
183    }
184    // 2. 通过数据操作选项获取数据。
185    unsigned int dataSize = 0;
186    OH_UdmfData* readData = nullptr;
187    if (OH_Udmf_GetUnifiedDataByOptions(options, &readData, &dataSize) != Udmf_ErrCode::UDMF_E_OK) {
188        OH_LOG_ERROR(LOG_APP, "Get Data error!");
189        OH_UdmfOptions_Destroy(options);
190        return;
191    }
192    OH_UdmfOptions_Destroy(options);
193    OH_LOG_INFO(LOG_APP, "the size of data is %{public}u", dataSize);
194    OH_UdmfData** dataArray = &readData;
195    for (unsigned int i = 0; i < dataSize; i++) {
196        OH_UdmfData* data = dataArray[i];
197        // 3. 判断OH_UdmfData是否有对应的类型。
198        if (!OH_UdmfData_HasType(data, UDMF_META_HYPERLINK)) {
199            OH_LOG_INFO(LOG_APP, "There is no hyperlink type in data[%{public}u].", i);
200            continue;
201        }
202        // 4. 获取数据记录和hyperlink数据。
203        unsigned int recordsCount = 0;
204        OH_UdmfRecord** records = OH_UdmfData_GetRecords(data, &recordsCount);
205        OH_LOG_INFO(LOG_APP, "the count of records count is %{public}u", recordsCount);    // 5. 获取records中的元素。
206        for (unsigned int j = 0; j < recordsCount; j++) {
207            // 获取OH_UdmfRecord类型列表。
208            unsigned int recordTypeIdCount = 0;
209            char** typeIdsFromRecord = OH_UdmfRecord_GetTypes(records[i], &recordTypeIdCount);
210            for (unsigned int k = 0; k < recordTypeIdCount; k++) {
211                // 从OH_UdmfRecord中获取超链接类型数据。
212                if (strcmp(typeIdsFromRecord[k], UDMF_META_HYPERLINK) == 0) {
213                    // 创建hyperlink的UDS,用来承载record中读取出来的hyperlink数据。
214                    OH_UdsHyperlink* hyperlink = OH_UdsHyperlink_Create();
215                    if (OH_UdmfRecord_GetHyperlink(records[j], hyperlink) != Udmf_ErrCode::UDMF_E_OK) {
216                        OH_LOG_ERROR(LOG_APP,"Fail get hyperlink from record!");
217                        OH_UdsHyperlink_Destroy(hyperlink);
218                        break;
219                    }
220                    // 读取OH_UdsHyperlink中的各项信息。
221                    OH_LOG_INFO(LOG_APP, "The hyperlink type id is : %{public}s", OH_UdsHyperlink_GetType(hyperlink));
222                    OH_LOG_INFO(LOG_APP, "The hyperlink url is : %{public}s", OH_UdsHyperlink_GetUrl(hyperlink));
223                    OH_LOG_INFO(LOG_APP, "The hyperlink description is : %{public}s", OH_UdsHyperlink_GetDescription(hyperlink));
224                    OH_UdsHyperlink_Destroy(hyperlink);
225                }
226            }
227        }
228    }
229    // 5. 销毁指针。
230    OH_Udmf_DestroyDataArray(dataArray, dataSize);
231}
232```
233
234## 使用UDMF更新UDS数据
235
236下面以更新超链接OH_UdsHyperlink类型数据场景为例,说明如何使用UDS与UDMF。
2371. 创建hyperlink的UDS数据结构。
2382. 设置hyperlink中的URL和描述信息。
2393. 创建OH_UdmfRecord对象,并向OH_UdmfRecord中添加超链接类型数据。
2404. 创建OH_UdmfData对象,并向OH_UdmfData中添加OH_UdmfRecord。
2415. 构建数据操作选项。
2426. 更新数据,将数据写入数据库中。
2437. 使用完成后销毁指针。
244
245```c
246void updateDataTest()
247{
248    // 1. 创建hyperlink的UDS数据结构。
249    OH_UdsHyperlink* hyperlink = OH_UdsHyperlink_Create();
250    // 2. 设置hyperlink中的URL和描述信息。
251    if (OH_UdsHyperlink_SetUrl(hyperlink, "www.demo2.com") != Udmf_ErrCode::UDMF_E_OK) {
252        OH_LOG_ERROR(LOG_APP, "Hyperlink set url error!");
253        OH_UdsHyperlink_Destroy(hyperlink);
254        return;
255    }
256    if (OH_UdsHyperlink_SetDescription(hyperlink, "This is the new description.") != Udmf_ErrCode::UDMF_E_OK) {
257        OH_LOG_ERROR(LOG_APP, "Hyperlink set description error!");
258        OH_UdsHyperlink_Destroy(hyperlink);
259        return;
260    }
261    // 3. 创建OH_UdmfRecord对象,并向OH_UdmfRecord中添加超链接类型数据。
262    OH_UdmfRecord* record = OH_UdmfRecord_Create();
263    if (OH_UdmfRecord_AddHyperlink(record, hyperlink) != Udmf_ErrCode::UDMF_E_OK) {
264        OH_LOG_ERROR(LOG_APP, "Add hyperlink to record error!");
265        OH_UdsHyperlink_Destroy(hyperlink);
266        OH_UdmfRecord_Destroy(record);
267        return;
268    }
269    // 4. 创建OH_UdmfData对象,并向OH_UdmfData中添加OH_UdmfRecord。
270    OH_UdmfData* data = OH_UdmfData_Create();
271    if (OH_UdmfData_AddRecord(data, record) != Udmf_ErrCode::UDMF_E_OK) {
272        OH_LOG_ERROR(LOG_APP, "Add record to data error!");
273        OH_UdsHyperlink_Destroy(hyperlink);
274        OH_UdmfRecord_Destroy(record);
275        OH_UdmfData_Destroy(data);
276        return;
277    }
278    // 5. 构建数据操作选项。
279    OH_UdmfOptions* options = OH_UdmfOptions_Create();
280    // 此处key为示例,不可直接使用,其值应与OH_Udmf_SetUnifiedDataByOptions接口中获取到的key值保持一致。
281    char key[] = "udmf://DataHub/com.ohos.test/0123456789";
282    if (OH_UdmfOptions_SetIntention(options, Udmf_Intention::UDMF_INTENTION_DATA_HUB) != Udmf_ErrCode::UDMF_E_OK
283        || OH_UdmfOptions_SetKey(options, key) != Udmf_ErrCode::UDMF_E_OK) {
284        OH_LOG_ERROR(LOG_APP, "Set option error!");
285        OH_UdsHyperlink_Destroy(hyperlink);
286        OH_UdmfRecord_Destroy(record);
287        OH_UdmfData_Destroy(data);
288        OH_UdmfOptions_Destroy(options);
289        return;
290    }
291    // 6. 更新数据,将数据写入数据库中。
292    if (OH_Udmf_UpdateUnifiedData(options, data) != Udmf_ErrCode::UDMF_E_OK) {
293        OH_LOG_ERROR(LOG_APP, "Update data error!");
294        OH_UdsHyperlink_Destroy(hyperlink);
295        OH_UdmfRecord_Destroy(record);
296        OH_UdmfData_Destroy(data);
297        OH_UdmfOptions_Destroy(options);
298        return;
299    }
300    OH_LOG_INFO(LOG_APP, "update data success");
301    // 7. 使用完成后销毁指针。
302    OH_UdsHyperlink_Destroy(hyperlink);
303    OH_UdmfRecord_Destroy(record);
304    OH_UdmfData_Destroy(data);
305    OH_UdmfOptions_Destroy(options);
306}
307```
308
309## 使用UDMF删除UDS数据
310
311下面继续以获取超链接OH_UdsHyperlink类型数据场景为例,说明如何使用UDS与UDMF。
3121. 构建数据操作选项。
3132. 通过数据操作选项删除数据。
3143. 判断OH_UdmfData是否有对应的类型。
3154. 获取数据记录和hyperlink数据。
3165. 获取数据记录中的元素。
3176. 销毁指针。
318
319```c
320void deleteDataTest()
321{
322    // 1. 构建数据操作选项。
323    OH_UdmfOptions* options = OH_UdmfOptions_Create();
324    if (OH_UdmfOptions_SetIntention(options, Udmf_Intention::UDMF_INTENTION_DATA_HUB) != Udmf_ErrCode::UDMF_E_OK) {
325        OH_LOG_ERROR(LOG_APP, "Set option error!");
326        OH_UdmfOptions_Destroy(options);
327        return;
328    }
329    // 2. 通过数据操作选项删除数据。
330    unsigned int dataSize = 0;
331    OH_UdmfData* readData = nullptr;
332    if (OH_Udmf_DeleteUnifiedData(options, &readData, &dataSize) != Udmf_ErrCode::UDMF_E_OK) {
333        OH_LOG_ERROR(LOG_APP, "Delete Data error!");
334        OH_UdmfOptions_Destroy(options);
335        return;
336    }
337    OH_UdmfOptions_Destroy(options);
338    OH_LOG_INFO(LOG_APP, "the size of data is %{public}u", dataSize);
339    OH_UdmfData** dataArray = &readData;
340    for (unsigned int i = 0; i < dataSize - 1; i++) {
341        OH_UdmfData* data = dataArray[i];
342        // 3. 判断OH_UdmfData是否有对应的类型。
343        if (!OH_UdmfData_HasType(data, UDMF_META_HYPERLINK)) {
344            OH_LOG_INFO(LOG_APP, "There is no hyperlink type in data[%{public}u].", i);
345            continue;
346        }
347        // 4. 获取数据记录和hyperlink数据。
348        unsigned int recordsCount = 0;
349        OH_UdmfRecord** records = OH_UdmfData_GetRecords(data, &recordsCount);
350        OH_LOG_INFO(LOG_APP, "the count of records count is %{public}u", recordsCount);
351        // 5. 获取数据记录中的元素。
352        for (unsigned int j = 0; j < recordsCount; j++) {
353            // 获取OH_UdmfRecord类型列表。
354            unsigned int recordTypeIdCount = 0;
355            char** typeIdsFromRecord = OH_UdmfRecord_GetTypes(records[i], &recordTypeIdCount);
356            for (unsigned int k = 0; k < recordTypeIdCount; k++) {
357                // 从OH_UdmfRecord中获取超链接类型数据。
358                if (strcmp(typeIdsFromRecord[k], UDMF_META_HYPERLINK) == 0) {
359                    // 创建hyperlink的UDS,用来承载record中读取出来的hyperlink数据。
360                    OH_UdsHyperlink* hyperlink = OH_UdsHyperlink_Create();
361                    if (OH_UdmfRecord_GetHyperlink(records[j], hyperlink) != Udmf_ErrCode::UDMF_E_OK) {
362                        OH_LOG_ERROR(LOG_APP,"Fail get hyperlink from record!");
363                        OH_UdsHyperlink_Destroy(hyperlink);
364                        break;
365                    }
366                    // 读取OH_UdsHyperlink中的各项信息。
367                    OH_LOG_INFO(LOG_APP, "The hyperlink type id is : %{public}s", OH_UdsHyperlink_GetType(hyperlink));
368                    OH_LOG_INFO(LOG_APP, "The hyperlink url is : %{public}s", OH_UdsHyperlink_GetUrl(hyperlink));
369                    OH_LOG_INFO(LOG_APP, "The hyperlink description is : %{public}s", OH_UdsHyperlink_GetDescription(hyperlink));
370                    OH_UdsHyperlink_Destroy(hyperlink);
371                }
372            }
373        }
374    }
375    // 6. 销毁指针。
376    OH_Udmf_DestroyDataArray(dataArray, dataSize);
377}
378```
379
380## 使用UDMF延迟写入UDS数据
381
382### 定义UDS数据提供函数
383
384下面以超链接hyperlink类型数据场景为例,说明如何定义一个提供UDS数据的回调函数。
3851. 定义OH_UdmfRecordProvider的数据提供函数。
3862. 在数据提供函数中,创建hyperlink类型的UDS数据结构。
3873. 设置hyperlink的URL和描述信息。
3884. 定义OH_UdmfRecordProvider销毁时触发的回调函数。
389
390```c
391// 为了代码可读性,代码中省略了各个步骤操作结果的校验,实际开发中需要确认每次调用的成功。
392// 1. 获取数据时触发的提供UDS数据的回调函数。
393static void* GetDataCallback(void* context, const char* type) {
394    if (strcmp(type, UDMF_META_HYPERLINK) == 0) {
395        // 2. 创建超链接hyperlink数据的UDS数据结构。
396        OH_UdsHyperlink* hyperlink = OH_UdsHyperlink_Create();
397        // 3. 设置hyperlink中的URL和描述信息。
398        OH_UdsHyperlink_SetUrl(hyperlink, "www.demo.com");
399        OH_UdsHyperlink_SetDescription(hyperlink, "This is the description.");
400        return hyperlink;
401    }
402    return nullptr;
403}
404// 4. OH_UdmfRecordProvider销毁时触发的回调函数。
405static void ProviderFinalizeCallback(void* context) { OH_LOG_INFO(LOG_APP, "OH_UdmfRecordProvider finalize."); }
406```
407
408### 延迟写入UDS数据
409
410下面以延迟写入超链接类型数据为例,说明如何使用OH_UdmfRecordProvider与UDMF。此步骤完成后,超链接类型数据并未真正写入数据库。只有当数据使用者从OH_UdmfRecord中获取OH_UdsHyperlink时,才会触发上文定义的`GetDataCallback`数据提供函数,从中获取数据。
411
4121. 创建OH_UdmfRecordProvider对象,设置它的数据提供函数和销毁回调函数。
4132. 创建OH_UdmfRecord对象,并配置OH_UdmfRecordProvider。
4143. 创建OH_UdmfData对象,并向OH_UdmfData中添加OH_UdmfRecord。
4154. 构建数据并写入数据库中,获取返回的Key值。
4165. 使用完成后销毁指针。
417
418```c
419void providerSetDataTest()
420{
421    // 为了代码可读性,代码中省略了各个步骤操作结果的校验,实际开发中需要确认每次调用的成功。
422    // 1. 创建一个OH_UdmfRecordProvider,设置它的数据提供函数和销毁回调函数。
423    OH_UdmfRecordProvider* provider = OH_UdmfRecordProvider_Create();
424    OH_UdmfRecordProvider_SetData(provider, (void* )provider, GetDataCallback, ProviderFinalizeCallback);
425
426    // 2. 创建OH_UdmfRecord对象,并配置OH_UdmfRecordProvider。
427    OH_UdmfRecord* record = OH_UdmfRecord_Create();
428    const char* types[1] = {UDMF_META_HYPERLINK};
429    OH_UdmfRecord_SetProvider(record, types, 1, provider);
430
431    // 3. 创建OH_UdmfData对象,并向OH_UdmfData中添加OH_UdmfRecord。
432    OH_UdmfData* data = OH_UdmfData_Create();
433    OH_UdmfData_AddRecord(data, record);
434
435    // 4. 构建数据并写入数据库中,获取返回的Key值。
436    OH_UdmfOptions* options = OH_UdmfOptions_Create();
437    if (OH_UdmfOptions_SetIntention(options, Udmf_Intention::UDMF_INTENTION_DATA_HUB) != Udmf_ErrCode::UDMF_E_OK) {
438        OH_LOG_ERROR(LOG_APP, "Set option error!");
439        OH_UdmfOptions_Destroy(options);
440        return;
441    }
442    char key[UDMF_KEY_BUFFER_LEN] = {0};
443    if (OH_Udmf_SetUnifiedDataByOptions(options, data, key, sizeof(key)) != Udmf_ErrCode::UDMF_E_OK) {
444        OH_LOG_ERROR(LOG_APP, "Set data error!");
445    }
446    OH_LOG_INFO(LOG_APP, "key = %{public}s", key);
447
448    // 5. 使用完成后销毁指针。
449    OH_UdmfRecord_Destroy(record);
450    OH_UdmfData_Destroy(data);
451    OH_UdmfOptions_Destroy(options);
452}
453```