1# 通过用户首选项实现数据持久化 (C/C++) 2 3## 场景介绍 4用户首选项(Preferences)模块主要提供轻量级Key-Value操作,支持本地应用存储少量数据,数据存储在本地文件中,同时也加载在内存中,所以访问速度更快,效率更高。首选项提供非关系型数据存储,不宜存储大量数据,经常用于操作键值对形式数据的场景。 5 6 7## 约束限制 81. Preferences不支持C API与ArkTS API混合使用。 92. Key的最大长度限制为1024个字节,Value的最大长度限制为16MB。 10 11 12## 接口说明 13 14详细的接口说明请参考[Preferences接口文档](../reference/apis-arkdata/_preferences.md)。 15 16| 接口名称 | 描述 | 17| -------- | -------- | 18| OH_Preferences \* OH_Preferences_Open (OH_PreferencesOption \*option, int \*errCode) | 打开一个Preferences实例对象并创建指向它的指针。 当不再需要使用指针时,请使用OH_Preferences_Close关闭实例对象。 | 19| int OH_Preferences_Close (OH_Preferences \*preference) | 关闭一个Preferences实例对象。 | 20| int OH_Preferences_GetInt (OH_Preferences \*preference, const char \*key, int \*value) | 获取Preferences实例对象中Key对应的整型值。 | 21| int OH_Preferences_GetBool (OH_Preferences \*preference, const char \*key, bool \*value) | 获取Preferences实例对象中Key对应的布尔值。 | 22| int OH_Preferences_GetString (OH_Preferences \*preference, const char \*key, char \*\*value, uint32_t \*valueLen) | 获取Preferences实例对象中Key对应的字符串。 | 23| void OH_Preferences_FreeString (char \*string) | 释放从Preferences实例对象中获取的字符串。 | 24| int OH_Preferences_SetInt (OH_Preferences \*preference, const char \*key, int value) | 根据Key设置Preferences实例对象中的整型值。 | 25| int OH_Preferences_SetBool (OH_Preferences \*preference, const char \*key, bool value) | 根据Key设置Preferences实例对象中的布尔值。 | 26| int OH_Preferences_SetString (OH_Preferences \*preference, const char \*key, const char \*value) | 根据Key设置Preferences实例对象中的字符串。 | 27| int OH_Preferences_Delete (OH_Preferences \*preference, const char \*key) | 在Preferences实例对象中删除Key对应的KV数据。 | 28| int OH_Preferences_RegisterDataObserver (OH_Preferences \*preference, void \*context, OH_PreferencesDataObserver observer, const char \*keys[], uint32_t keyCount) | 对选取的Key注册数据变更订阅。订阅的Key的值发生变更后,在调用OH_Preferences_Close()后触发回调。 | 29| int OH_Preferences_UnregisterDataObserver (OH_Preferences \*preference, void \*context, OH_PreferencesDataObserver observer, const char \*keys[], uint32_t keyCount) | 取消注册选取Key的数据变更订阅。 | 30| OH_PreferencesOption \* OH_PreferencesOption_Create (void) | 创建一个Preferences配置选项的OH_PreferencesOption实例对象以及指向它的指针。 当不再需要使用指针时,请使用OH_PreferencesOption_Destroy销毁实例对象,否则会导致内存泄漏。 | 31| int OH_PreferencesOption_SetFileName (OH_PreferencesOption \*option, const char \*fileName) | 设置Preferences配置选项OH_PreferencesOption实例对象的文件名称。名称长度需大于零且小于等于255字节,名称中不能包含'/'且不能以'/'结尾。 | 32| int OH_PreferencesOption_SetBundleName (OH_PreferencesOption \*option, const char \*bundleName) | 设置Preferences配置选项OH_PreferencesOption实例对象的包名称。 | 33| int OH_PreferencesOption_SetDataGroupId (OH_PreferencesOption \*option, const char \*dataGroupId) | 设置Preferences配置选项OH_PreferencesOption实例对象的应用组ID。 | 34| int OH_PreferencesOption_Destroy (OH_PreferencesOption \*option) | 销毁Preferences配置选项OH_PreferencesOption实例。 | 35| const char \* OH_PreferencesPair_GetKey (const OH_PreferencesPair \*pairs, uint32_t index) | 获取KV数据中索引对应数据的键。 | 36| const OH_PreferencesValue \* OH_PreferencesPair_GetPreferencesValue (const OH_PreferencesPair \*pairs, uint32_t index) | 获取KV数据数组中索引对应的值。 | 37| Preference_ValueType OH_PreferencesValue_GetValueType (const OH_PreferencesValue \*object) | 获取PreferencesValue对象的数据类型。 | 38| int OH_PreferencesValue_GetInt (const OH_PreferencesValue \*object, int \*value) | 从PreferencesValue对象OH_PreferencesValue中获取一个整型值。 | 39| int OH_PreferencesValue_GetBool (const OH_PreferencesValue \*object, bool \*value) | 从PreferencesValue对象OH_PreferencesValue中获取一个布尔值。 | 40| int OH_PreferencesValue_GetString (const OH_PreferencesValue \*object, char \*\*value, uint32_t \*valueLen) | 从PreferencesValue对象OH_PreferencesValue中获取字符串。 | 41 42 43## 添加动态链接库 44 45CMakeLists.txt中添加以下lib。 46 47```txt 48libohpreferences.so 49``` 50 51## 引用头文件 52 53```c 54#include <cstring> 55#include <database/preferences/oh_preferences.h> 56#include <database/preferences/oh_preferences_err_code.h> 57#include <database/preferences/oh_preferences_option.h> 58#include <database/preferences/oh_preferences_value.h> 59``` 60 61## 开发步骤 62下列实例展示如何通过Preferences实现对KV数据的修改与持久化。 631. 创建Preferences配置选项(PreferencesOption)对象并设置配置选项成员,配置选项实例使用完后需要调用OH_PreferencesOption_Destroy销毁。 642. 调用OH_Preferences_Open打开一个Preferences实例,该实例使用完后需要调用OH_Preferences_Close关闭。 653. 调用OH_Preferences_RegisterDataObserver注册3个Key的数据变更订阅,订阅回调函数为DataChangeObserverCallback。 664. 设置Preferences实例中的KV数据。 675. 获取Preferences实例中的KV数据。 686. 调用OH_Preferences_Close关闭Preferences实例,关闭后需要将实例指针置空。 69 70```c 71// 数据变更回调函数 72void DataChangeObserverCallback(void *context, const OH_PreferencesPair *pairs, uint32_t count) { 73 for (uint32_t i = 0; i < count; i++) { 74 // 获取索引i对应的PreferenceValue 75 const OH_PreferencesValue *pValue = OH_PreferencesPair_GetPreferencesValue(pairs, i); 76 // 获取PreferencesValue的数据类型 77 Preference_ValueType type = OH_PreferencesValue_GetValueType(pValue); 78 int ret = PREFERENCES_OK; 79 if (type == PREFERENCE_TYPE_INT) { 80 int intValue = 0; 81 ret = OH_PreferencesValue_GetInt(pValue, &intValue); 82 if (ret == PREFERENCES_OK) { 83 // 业务逻辑 84 } 85 } else if (type == PREFERENCE_TYPE_BOOL) { 86 bool boolValue = true; 87 ret = OH_PreferencesValue_GetBool(pValue, &boolValue); 88 if (ret == PREFERENCES_OK) { 89 // 业务逻辑 90 } 91 } else if (type == PREFERENCE_TYPE_STRING) { 92 char *stringValue = nullptr; 93 uint32_t valueLen = 0; 94 ret = OH_PreferencesValue_GetString(pValue, &stringValue, &valueLen); 95 if (ret == PREFERENCES_OK) { 96 // 业务逻辑 97 OH_Preferences_FreeString(stringValue); 98 } 99 } else { 100 // 无效类型 101 } 102 } 103} 104 105// 1. 创建Preferences配置选项。 106OH_PreferencesOption *option = OH_PreferencesOption_Create(); 107if (option == nullptr) { 108 // 错误处理 109} 110// 设置Preferences配置选项的文件名称。 111int ret = OH_PreferencesOption_SetFileName(option, "testdb"); 112if (ret != PREFERENCES_OK) { 113 (void)OH_PreferencesOption_Destroy(option); 114 // 错误处理 115} 116// 设置Preferences配置选项的应用组ID。 117ret = OH_PreferencesOption_SetDataGroupId(option, ""); 118if (ret != PREFERENCES_OK) { 119 (void)OH_PreferencesOption_Destroy(option); 120 // 错误处理 121} 122// 设置Preferences配置选项的包名称。 123ret = OH_PreferencesOption_SetBundleName(option, "com.example"); 124if (ret != PREFERENCES_OK) { 125 (void)OH_PreferencesOption_Destroy(option); 126 // 错误处理 127} 128 129// 2. 打开一个Preferences实例。 130int errCode = PREFERENCES_OK; 131OH_Preferences *preference = OH_Preferences_Open(option, &errCode); 132// option使用完毕后可直接释放,释放后需要将指针置空。 133(void)OH_PreferencesOption_Destroy(option); 134option = nullptr; 135if (preference == nullptr) { 136 // 错误处理 137} 138 139// 3. 对key_int、key_bool和key_string注册数据变更订阅。 140const char *keys[] = {"key_int", "key_bool", "key_string"}; 141ret = OH_Preferences_RegisterDataObserver(preference, nullptr, DataChangeObserverCallback, keys, 3); 142if (ret != PREFERENCES_OK) { 143 (void)OH_Preferences_Close(preference); 144 // 错误处理 145} 146 147// 4. 设置Preferences实例中的KV数据。 148ret = OH_Preferences_SetInt(preference, keys[0], 0); 149if (ret != PREFERENCES_OK) { 150 (void)OH_Preferences_Close(preference); 151 // 错误处理 152} 153ret = OH_Preferences_SetBool(preference, keys[1], true); 154if (ret != PREFERENCES_OK) { 155 (void)OH_Preferences_Close(preference); 156 // 错误处理 157} 158ret = OH_Preferences_SetString(preference, keys[2], "string value"); 159if (ret != PREFERENCES_OK) { 160 (void)OH_Preferences_Close(preference); 161 // 错误处理 162} 163 164// 5. 获取Preferences实例中的KV数据。 165int intValue = 0; 166ret = OH_Preferences_GetInt(preference, keys[0], &intValue); 167if (ret == PREFERENCES_OK) { 168 // 业务逻辑 169} 170 171bool boolValue = false; 172ret = OH_Preferences_GetBool(preference, keys[1], &boolValue); 173if (ret == PREFERENCES_OK) { 174 // 业务逻辑 175} 176 177char *stringValue = nullptr; 178uint32_t valueLen = 0; 179ret = OH_Preferences_GetString(preference, keys[2], &stringValue, &valueLen); 180if (ret == PREFERENCES_OK) { 181 // 业务逻辑 182 // 使用完OH_Preferences_GetString接口后,需要对字符串进行释放。 183 OH_Preferences_FreeString(stringValue); 184 stringValue = nullptr; 185} 186 187// 6. 使用完Preferences实例后需要关闭实例,关闭后需要将指针置空。 188(void)OH_Preferences_Close(preference); 189preference = nullptr; 190 191``` 192