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```