文档管理中心
我的
您当前正在浏览新版开发者文档中心,目录分类和层级有所调整。点击左侧当前文档分类名称前的“☰”图标,可切换文档分类。 了解新版目录
指南与API参考指南应用框架ArkData(方舟数据管理)应用数据持久化通过用户首选项实现数据持久化 (C/C++)

通过用户首选项实现数据持久化 (C/C++)

场景介绍

用户首选项(Preferences)模块主要提供轻量级Key-Value操作,支持本地存储少量数据,数据存储在文件和内存中,访问速度快。如果存在大量数据场景,请考虑使用键值型数据库或关系型数据库。

约束限制

  • API version 18之前:ArkTS API仅支持XML存储模式;C API仅支持GSKV存储模式;存储模式互不兼容,不支持ArkTS和C API操作同一个Preferences实例。
  • API version 18及之后:ArkTS和C API均支持XML和GSKV双模式;ArkTS和C API使用相同的存储模式时,可以正常操作同一Preferences实例;禁止ArkTS和C API选择不同的存储模式,来操作同一个Preferences实例。
  • Key的最大长度限制为1024个字节,Value的最大长度限制为16MB。

接口说明

详细的接口说明请参考Preferences接口文档。

展开
接口名称 描述
OH_Preferences * OH_Preferences_Open (OH_PreferencesOption *option, int *errCode) 打开一个Preferences实例对象并创建指向它的指针。 当不再需要使用指针时,请使用OH_Preferences_Close关闭实例对象。
int OH_Preferences_Close (OH_Preferences *preference) 关闭一个Preferences实例对象。
int OH_Preferences_GetInt (OH_Preferences *preference, const char *key, int *value) 获取Preferences实例对象中Key对应的整型值。
int OH_Preferences_GetBool (OH_Preferences *preference, const char *key, bool *value) 获取Preferences实例对象中Key对应的布尔值。
int OH_Preferences_GetString (OH_Preferences *preference, const char *key, char **value, uint32_t *valueLen) 获取Preferences实例对象中Key对应的字符串。
void OH_Preferences_FreeString (char *string) 释放从Preferences实例对象中获取的字符串。
int OH_Preferences_SetInt (OH_Preferences *preference, const char *key, int value) 根据Key设置Preferences实例对象中的整型值。
int OH_Preferences_SetBool (OH_Preferences *preference, const char *key, bool value) 根据Key设置Preferences实例对象中的布尔值。
int OH_Preferences_SetString (OH_Preferences *preference, const char *key, const char *value) 根据Key设置Preferences实例对象中的字符串。
int OH_Preferences_Delete (OH_Preferences *preference, const char *key) 在Preferences实例对象中删除Key对应的KV数据。
int OH_Preferences_RegisterDataObserver (OH_Preferences *preference, void *context, OH_PreferencesDataObserver observer, const char *keys[], uint32_t keyCount) 对选取的Key注册数据变更订阅。订阅的Key的值发生变更后,在调用OH_Preferences_Close()后触发回调。
int OH_Preferences_UnregisterDataObserver (OH_Preferences *preference, void *context, OH_PreferencesDataObserver observer, const char *keys[], uint32_t keyCount) 取消注册选取Key的数据变更订阅。
int OH_Preferences_IsStorageTypeSupported (Preferences_StorageType type, bool *isSupported) 检查当前平台是否支持对应的存储模式。
OH_PreferencesOption * OH_PreferencesOption_Create (void) 创建一个Preferences配置选项的OH_PreferencesOption实例对象以及指向它的指针。 当不再需要使用指针时,请使用OH_PreferencesOption_Destroy销毁实例对象,否则会导致内存泄漏。
int OH_PreferencesOption_SetFileName (OH_PreferencesOption *option, const char *fileName) 设置Preferences配置选项OH_PreferencesOption实例对象的文件名称。名称长度为0到255字节,其中不能包含'/'。
int OH_PreferencesOption_SetBundleName (OH_PreferencesOption *option, const char *bundleName) 设置Preferences配置选项OH_PreferencesOption实例对象的包名称。
int OH_PreferencesOption_SetDataGroupId (OH_PreferencesOption *option, const char *dataGroupId) 设置Preferences配置选项OH_PreferencesOption实例对象的应用组ID。
int OH_PreferencesOption_SetStorageType (OH_PreferencesOption *option, Preferences_StorageType type) 设置Preferences配置选项 OH_PreferencesOption实例对象的存储模式。
int OH_PreferencesOption_Destroy (OH_PreferencesOption *option) 销毁Preferences配置选项OH_PreferencesOption实例。
const char * OH_PreferencesPair_GetKey (const OH_PreferencesPair *pairs, uint32_t index) 获取KV数据中索引对应数据的键。
const OH_PreferencesValue * OH_PreferencesPair_GetPreferencesValue (const OH_PreferencesPair *pairs, uint32_t index) 获取KV数据数组中索引对应的值。
Preference_ValueType OH_PreferencesValue_GetValueType (const OH_PreferencesValue *object) 获取PreferencesValue对象的数据类型。
int OH_PreferencesValue_GetInt (const OH_PreferencesValue *object, int *value) 从PreferencesValue对象OH_PreferencesValue中获取一个整型值。
int OH_PreferencesValue_GetBool (const OH_PreferencesValue *object, bool *value) 从PreferencesValue对象OH_PreferencesValue中获取一个布尔值。
int OH_PreferencesValue_GetString (const OH_PreferencesValue *object, char **value, uint32_t *valueLen) 从PreferencesValue对象OH_PreferencesValue中获取字符串。

添加动态链接库

CMakeLists.txt中添加以下lib。

收起
自动换行
深色代码主题
复制
  1. libohpreferences.so

引用头文件

收起
自动换行
深色代码主题
复制
  1. #include <database/preferences/oh_preferences.h>
  2. #include <database/preferences/oh_preferences_err_code.h>
  3. #include <database/preferences/oh_preferences_option.h>
  4. #include <database/preferences/oh_preferences_value.h>

开发步骤

下列实例展示如何通过Preferences实现对键值数据的修改与持久化。

  1. 创建Preferences配置选项(PreferencesOption)对象并设置配置选项成员(名称、应用组ID、包名、存储模式)。使用完毕后,调用OH_PreferencesOption_Destroy销毁配置选项实例。

  2. 调用OH_Preferences_Open打开一个Preferences实例,该实例使用完后需要调用OH_Preferences_Close关闭。

    收起
    自动换行
    深色代码主题
    复制
    1. // 1. 创建Preferences配置选项。
    2. OH_PreferencesOption *option = OH_PreferencesOption_Create();
    3. if (option == nullptr) {
    4. // 错误处理
    5. }
    6. // 设置Preferences配置选项的文件名称。
    7. int ret = OH_PreferencesOption_SetFileName(option, "testdb");
    8. if (ret != PREFERENCES_OK) {
    9. (void)OH_PreferencesOption_Destroy(option);
    10. // 错误处理
    11. }
    12. // 设置Preferences配置选项的应用组ID。
    13. ret = OH_PreferencesOption_SetDataGroupId(option, "");
    14. if (ret != PREFERENCES_OK) {
    15. (void)OH_PreferencesOption_Destroy(option);
    16. // 错误处理
    17. }
    18. // 设置Preferences配置选项的包名称。
    19. ret = OH_PreferencesOption_SetBundleName(option, "com.example");
    20. if (ret != PREFERENCES_OK) {
    21. (void)OH_PreferencesOption_Destroy(option);
    22. // 错误处理
    23. }
    24. // 设置Preferences配置选项的存储模式,需要注意的是,设置之前需要调用OH_Preferences_IsStorageTypeSupported接口判断当前平台是否支持需要选择的模式。
    25. bool isGskvSupported = false;
    26. ret = OH_Preferences_IsStorageTypeSupported(Preferences_StorageType::PREFERENCES_STORAGE_GSKV, &isGskvSupported);
    27. if (ret != PREFERENCES_OK) {
    28. (void)OH_PreferencesOption_Destroy(option);
    29. // 错误处理
    30. }
    31. if (isGskvSupported) {
    32. ret = OH_PreferencesOption_SetStorageType(option, Preferences_StorageType::PREFERENCES_STORAGE_GSKV);
    33. if (ret != PREFERENCES_OK) {
    34. (void)OH_PreferencesOption_Destroy(option);
    35. // 错误处理
    36. }
    37. } else {
    38. ret = OH_PreferencesOption_SetStorageType(option, Preferences_StorageType::PREFERENCES_STORAGE_XML);
    39. if (ret != PREFERENCES_OK) {
    40. (void)OH_PreferencesOption_Destroy(option);
    41. // 错误处理
    42. }
    43. }
    44. // 2. 打开一个Preferences实例。
    45. int errCode = PREFERENCES_OK;
    46. OH_Preferences *preference = OH_Preferences_Open(option, &errCode);
    47. // option使用完毕后可直接释放,释放后需要将指针置空。
    48. (void)OH_PreferencesOption_Destroy(option);
    49. option = nullptr;
    50. if (preference == nullptr || errCode != PREFERENCES_OK) {
    51. // 错误处理
    52. }
    53. // option使用完毕后删除配置选项
    54. errCode = OH_Preferences_DeletePreferences(option);
    55. if (errCode != PREFERENCES_OK) {
    56. // 错误处理
    57. }
  3. 订阅回调函数为DataChangeObserverCallback。

    收起
    自动换行
    深色代码主题
    复制
    1. // 数据变更回调函数
    2. void DataChangeObserverCallback(void *context, const OH_PreferencesPair *pairs, uint32_t count)
    3. {
    4. for (uint32_t i = 0; i < count; i++) {
    5. // 获取索引i对应的PreferencesValue
    6. const OH_PreferencesValue *pValue = OH_PreferencesPair_GetPreferencesValue(pairs, i);
    7. // 获取PreferencesValue的数据类型
    8. Preference_ValueType type = OH_PreferencesValue_GetValueType(pValue);
    9. int ret = PREFERENCES_OK;
    10. if (type == PREFERENCE_TYPE_INT) {
    11. int intValue = 0;
    12. ret = OH_PreferencesValue_GetInt(pValue, &intValue);
    13. if (ret == PREFERENCES_OK) {
    14. // 业务逻辑
    15. }
    16. } else if (type == PREFERENCE_TYPE_BOOL) {
    17. bool boolValue = true;
    18. ret = OH_PreferencesValue_GetBool(pValue, &boolValue);
    19. if (ret == PREFERENCES_OK) {
    20. // 业务逻辑
    21. }
    22. } else if (type == PREFERENCE_TYPE_STRING) {
    23. char *stringValue = nullptr;
    24. uint32_t valueLen = 0;
    25. ret = OH_PreferencesValue_GetString(pValue, &stringValue, &valueLen);
    26. if (ret == PREFERENCES_OK) {
    27. // 业务逻辑
    28. OH_Preferences_FreeString(stringValue);
    29. }
    30. } else {
    31. // 无效类型
    32. }
    33. }
    34. }

    调用OH_Preferences_RegisterDataObserver注册3个Key的数据变更订阅。

    收起
    自动换行
    深色代码主题
    复制
    1. // 3. 对key_int、key_bool和key_string注册数据变更订阅。
    2. const char *keys[] = {"key_int", "key_bool", "key_string"};
    3. int ret = OH_Preferences_RegisterDataObserver(preference, nullptr, DataChangeObserverCallback, keys, 3);
    4. if (ret != PREFERENCES_OK) {
    5. (void)OH_Preferences_Close(preference);
    6. // 错误处理
    7. }
    8. // 兼容多种类型的注册数据变更订阅。
    9. int contextData = 42;
    10. ret = OH_Preferences_RegisterMultiProcessDataObserver(preference, &contextData, DataChangeObserverCallback);
    11. if (ret != PREFERENCES_OK) {
    12. // 错误处理
    13. }
    14. // 取消兼容多种类型的注册数据变更订阅。
    15. ret = OH_Preferences_UnregisterMultiProcessDataObserver(preference, &contextData, DataChangeObserverCallback);
    16. if (ret != PREFERENCES_OK) {
    17. // 错误处理
    18. }
  4. 设置Preferences实例中的键值数据。

    收起
    自动换行
    深色代码主题
    复制
    1. // 4. 设置Preferences实例中的KV数据。
    2. ret = OH_Preferences_SetInt(preference, keys[0], 0);
    3. if (ret != PREFERENCES_OK) {
    4. (void)OH_Preferences_Close(preference);
    5. // 错误处理
    6. }
    7. ret = OH_Preferences_SetBool(preference, keys[1], true);
    8. if (ret != PREFERENCES_OK) {
    9. (void)OH_Preferences_Close(preference);
    10. // 错误处理
    11. }
    12. int32_t stringIndex = 2;
    13. ret = OH_Preferences_SetString(preference, keys[stringIndex], "string value");
    14. if (ret != PREFERENCES_OK) {
    15. (void)OH_Preferences_Close(preference);
    16. // 错误处理
    17. }
    18. ret = OH_Preferences_Flush(preference);
    19. if (ret != PREFERENCES_OK) {
    20. (void)OH_Preferences_Close(preference);
    21. // 错误处理
    22. }
    23. OH_PreferencesValue* setIntValue = OH_PreferencesValue_Create();
    24. if (setIntValue == nullptr) {
    25. // 错误处理
    26. }
    27. const int value = 456;
    28. ret = OH_PreferencesValue_SetInt(setIntValue, value);
    29. if (ret != PREFERENCES_OK) {
    30. (void)OH_PreferencesValue_Destroy(setIntValue);
    31. // 错误处理
    32. }
    33. ret = OH_Preferences_SetValue(preference, "int_key", setIntValue);
    34. if (ret != PREFERENCES_OK) {
    35. (void)OH_Preferences_Close(preference);
    36. // 错误处理
    37. }
  5. 获取Preferences实例中的键值数据。

    收起
    自动换行
    深色代码主题
    复制
    1. // 5. 获取Preferences实例中的KV数据。
    2. int intValue = 0;
    3. int ret = PREFERENCES_OK;
    4. const char *keys[] = {"key_int", "key_bool", "key_string"};
    5. ret = OH_Preferences_GetInt(preference, keys[0], &intValue);
    6. if (ret == PREFERENCES_OK) {
    7. // 业务逻辑
    8. }
    9. bool boolValue = false;
    10. ret = OH_Preferences_GetBool(preference, keys[1], &boolValue);
    11. if (ret == PREFERENCES_OK) {
    12. // 业务逻辑
    13. }
    14. char *stringValue = nullptr;
    15. uint32_t valueLen = 0;
    16. int32_t stringIndex = 2;
    17. ret = OH_Preferences_GetString(preference, keys[stringIndex], &stringValue, &valueLen);
    18. if (ret == PREFERENCES_OK) {
    19. // 业务逻辑
    20. // 使用完OH_Preferences_GetString接口后,需要对字符串进行释放。
    21. OH_Preferences_FreeString(stringValue);
    22. stringValue = nullptr;
    23. }
    24. OH_PreferencesValue* getIntValue = OH_PreferencesValue_Create();
    25. if (getIntValue == nullptr) {
    26. // 错误处理
    27. }
    28. ret = OH_Preferences_GetValue(preference, "int_key", &getIntValue);
    29. if (ret == PREFERENCES_OK) {
    30. // 业务逻辑
    31. }
    32. OH_PreferencesPair* pairs = nullptr;
    33. uint32_t count = 0;
    34. ret = OH_Preferences_GetAll(preference, &pairs, &count);
    35. if (ret == PREFERENCES_OK) {
    36. // 业务逻辑
    37. if (pairs != nullptr) {
    38. // 销毁例对象中所有的KV数据。
    39. OH_PreferencesPair_Destroy(pairs, count);
    40. }
    41. }
    42. // 查询Preferences实例中的Key是否有数据
    43. bool result = OH_Preferences_HasKey(preference, "int_key");
    44. if (result == true) {
    45. // 有数据 业务逻辑
    46. }
    47. // 清理缓存数据
    48. ret = OH_Preferences_ClearCache(preference);
  6. 调用OH_Preferences_Close关闭Preferences实例,关闭后需要将实例指针置空。

    收起
    自动换行
    深色代码主题
    复制
    1. // 6. 使用完Preferences实例后需要关闭实例,关闭后需要将指针置空。
    2. (void)OH_Preferences_Close(preference);
    3. preference = nullptr;
  7. 设置和获取OH_PreferencesValue数据。

    收起
    自动换行
    深色代码主题
    复制
    1. const int arg5 = 5;
    2. const int arg4 = 4;
    3. const int arg3 = 3;
    4. int ret = PREFERENCES_OK;
    5. OH_PreferencesValue* setValue = OH_PreferencesValue_Create();
    6. bool boolArray[] = {true, false, true, false};
    7. ret = OH_PreferencesValue_SetBoolArray(setValue, boolArray, arg4);
    8. if (ret != PREFERENCES_OK) {
    9. // 错误处理
    10. }
    11. uint32_t count = 0;
    12. bool* outBoolArray = nullptr;
    13. ret = OH_PreferencesValue_GetBoolArray(setValue, &outBoolArray, &count);
    14. if (ret != PREFERENCES_OK) {
    15. // 错误处理
    16. }
    17. const char* strArray[] = {"hello", "world", "test"};
    18. ret = OH_PreferencesValue_SetStringArray(setValue, strArray, arg3);
    19. if (ret != PREFERENCES_OK) {
    20. // 错误处理
    21. }
    22. char** outStrArray = nullptr;
    23. ret = OH_PreferencesValue_GetStringArray(setValue, &outStrArray, &count);
    24. if (ret != PREFERENCES_OK) {
    25. // 错误处理
    26. }
    27. int64_t int64Array[] = {1234567890LL, 9876543210LL, -1234567890LL};
    28. ret = OH_PreferencesValue_SetInt64Array(setValue, int64Array, arg3);
    29. if (ret != PREFERENCES_OK) {
    30. // 错误处理
    31. }
    32. int64_t* outArrayInt64 = nullptr;
    33. ret = OH_PreferencesValue_GetInt64Array(setValue, &outArrayInt64, &count);
    34. if (ret != PREFERENCES_OK) {
    35. // 错误处理
    36. }
    37. double doubleArray[] = {1.1, 2.2, 3.3, 4.4};
    38. ret = OH_PreferencesValue_SetDoubleArray(setValue, doubleArray, arg4);
    39. if (ret != PREFERENCES_OK) {
    40. // 错误处理
    41. }
    42. double* outDoubleArray = nullptr;
    43. ret = OH_PreferencesValue_GetDoubleArray(setValue, &outDoubleArray, &count);
    44. if (ret != PREFERENCES_OK) {
    45. // 错误处理
    46. }
    47. uint8_t blobData[] = {0x01, 0x02, 0x03, 0x04, 0x05};
    48. ret = OH_PreferencesValue_SetBlob(setValue, blobData, arg5);
    49. if (ret != PREFERENCES_OK) {
    50. // 错误处理
    51. }
    52. uint8_t* outBlob = nullptr;
    53. ret = OH_PreferencesValue_GetBlob(setValue, &outBlob, &count);
    54. if (ret != PREFERENCES_OK) {
    55. // 错误处理
    56. }