• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Persisting User Preference Data (C/C++)
2
3## When to Use
4Use the **Preferences** module to store small amounts of data in key-value (KV) format. The data is stored in files and memory for fast access. If a large amount of data needs to be stored, consider using a KV store or RDB store.
5
6## Constraints
7- Prior to API version 18: ArkTS APIs support only the XML storage format, and C APIs support only the GSKV storage format. Due to incompatible formats, ArkTS and C APIs cannot operate the same **Preferences** instance.
8- API version 18 and later: Both ArkTS and C APIs support the XML and GSKV storage formats. ArkTS and C APIs can operate the same **Preferences** instance if they use the same format.
9- The maximum key length is 1024 bytes, and the maximum value length is 16 MB.
10
11
12## Available APIs
13
14For details about the APIs, see [Preferences](../reference/apis-arkdata/capi-preferences.md).
15
16| API| Description|
17| -------- | -------- |
18| OH_Preferences \* OH_Preferences_Open (OH_PreferencesOption \*option, int \*errCode) | Opens a **Preferences** instance and creates a pointer to it. If the pointer is no longer required, use **OH_Preferences_Close** to close the instance.|
19| int OH_Preferences_Close (OH_Preferences \*preference) | Closes a **Preferences** instance.|
20| int OH_Preferences_GetInt (OH_Preferences \*preference, const char \*key, int \*value) | Obtains an integer corresponding to the specified key in a **Preferences** instance.|
21| int OH_Preferences_GetBool (OH_Preferences \*preference, const char \*key, bool \*value) | Obtains a Boolean value corresponding to the specified key in a **Preferences** instance.|
22| int OH_Preferences_GetString (OH_Preferences \*preference, const char \*key, char \*\*value, uint32_t \*valueLen) | Obtains a string corresponding to the specified key in a **Preferences** instance.|
23| void OH_Preferences_FreeString (char \*string) | Releases a string.|
24| int OH_Preferences_SetInt (OH_Preferences \*preference, const char \*key, int value) | Sets an integer based on the specified key in a **Preferences** instance.|
25| int OH_Preferences_SetBool (OH_Preferences \*preference, const char \*key, bool value) | Sets a Boolean value based on the specified key in a **Preferences** instance.|
26| int OH_Preferences_SetString (OH_Preferences \*preference, const char \*key, const char \*value) | Sets a string based on the specified key in a **Preferences** instance.|
27| int OH_Preferences_Delete (OH_Preferences \*preference, const char \*key) | Deletes the KV data corresponding to the specified key from a **Preferences** instance.|
28| int OH_Preferences_RegisterDataObserver (OH_Preferences \*preference, void \*context, OH_PreferencesDataObserver observer, const char \*keys[], uint32_t keyCount) | Subscribes to data changes of the specified keys. If the value of the specified key changes, a callback will be invoked after **OH_Preferences_Close()** is called.|
29| int OH_Preferences_UnregisterDataObserver (OH_Preferences \*preference, void \*context, OH_PreferencesDataObserver observer, const char \*keys[], uint32_t keyCount) | Unsubscribes from data changes of the specified keys.|
30| int OH_Preferences_IsStorageTypeSupported (Preferences_StorageType type, bool \*isSupported) | Checks whether the specified storage type is supported.|
31| OH_PreferencesOption \* OH_PreferencesOption_Create (void) | Creates an **OH_PreferencesOption** instance and a pointer to it. If this pointer is no longer required, use **OH_PreferencesOption_Destroy** to destroy it. Otherwise, memory leaks may occur.|
32| int OH_PreferencesOption_SetFileName (OH_PreferencesOption \*option, const char \*fileName) | Sets the file name for an **OH_PreferencesOption** instance. The file name cannot contain a slash (/) or exceed 255 bytes.|
33| int OH_PreferencesOption_SetBundleName (OH_PreferencesOption \*option, const char \*bundleName) | Sets the bundle name for an OH_PreferencesOption instance.|
34| int OH_PreferencesOption_SetDataGroupId (OH_PreferencesOption \*option, const char \*dataGroupId) | Sets the application group ID for an **OH_PreferencesOption** instance.|
35| int OH_PreferencesOption_SetStorageType (OH_PreferencesOption \*option, Preferences_StorageType type) | Sets the storage type for an **OH_PreferencesOption** instance.|
36| int OH_PreferencesOption_Destroy (OH_PreferencesOption \*option) | Destroys an **OH_PreferencesOption** instance.|
37| const char \* OH_PreferencesPair_GetKey (const OH_PreferencesPair \*pairs, uint32_t index) | Obtains the key based on the specified index from the KV data.|
38| const OH_PreferencesValue \* OH_PreferencesPair_GetPreferencesValue (const OH_PreferencesPair \*pairs, uint32_t index) | Obtains the value based on the specified index from the KV pairs.|
39| Preference_ValueType OH_PreferencesValue_GetValueType (const OH_PreferencesValue \*object) | Obtains the data type of a **PreferencesValue** instance.|
40| int OH_PreferencesValue_GetInt (const OH_PreferencesValue \*object, int \*value) | Obtains an integer value from an **OH_PreferencesValue** instance.|
41| int OH_PreferencesValue_GetBool (const OH_PreferencesValue \*object, bool \*value) | Obtains a Boolean value from an **OH_PreferencesValue** instance.|
42| int OH_PreferencesValue_GetString (const OH_PreferencesValue \*object, char \*\*value, uint32_t \*valueLen) | Obtains a string from an **OH_PreferencesValue** instance.|
43
44
45## Adding Dynamic Link Libraries
46
47Add the following library to **CMakeLists.txt**.
48
49```txt
50libohpreferences.so
51```
52
53## Including Header Files
54
55```c
56#include <cstring>
57#include <database/preferences/oh_preferences.h>
58#include <database/preferences/oh_preferences_err_code.h>
59#include <database/preferences/oh_preferences_option.h>
60#include <database/preferences/oh_preferences_value.h>
61```
62
63## How to Develop
64The following example shows how to use **Preferences** APIs to modify and persist KV data.
651. Create a **PreferencesOption** instance and set the name, application group ID, bundle name, and storage type. If the **PreferencesOption** object is no longer required, call **OH_PreferencesOption_Destroy** to destroy it.
662. Call **OH_Preferences_Open** to open a **Preferences** instance. When the **Preferences** instance is not required, call **OH_Preferences_Close** to close it.
673. Call **OH_Preferences_RegisterDataObserver** to register a **DataChangeObserverCallback** callback to observe data changes of three keys.
684. Set KV data in the **Preferences** instance.
695. Obtain data in the **Preferences** instance.
706. Call **OH_Preferences_Close** to close the **Preferences** instance and set the instance pointer to null.
71
72```c
73// Callback used to return data changes.
74void DataChangeObserverCallback(void *context, const OH_PreferencesPair *pairs, uint32_t count) {
75    for (uint32_t i = 0; i < count; i++) {
76        // Obtain the value corresponding to index i.
77        const OH_PreferencesValue *pValue = OH_PreferencesPair_GetPreferencesValue(pairs, i);
78        // Obtain the data type of a value.
79        Preference_ValueType type = OH_PreferencesValue_GetValueType(pValue);
80        int ret = PREFERENCES_OK;
81        if (type == PREFERENCE_TYPE_INT) {
82            int intValue = 0;
83            ret = OH_PreferencesValue_GetInt(pValue, &intValue);
84            if (ret == PREFERENCES_OK) {
85                // Service logic.
86            }
87        } else if (type == PREFERENCE_TYPE_BOOL) {
88            bool boolValue = true;
89            ret = OH_PreferencesValue_GetBool(pValue, &boolValue);
90            if (ret == PREFERENCES_OK) {
91                // Service logic.
92            }
93        } else if (type == PREFERENCE_TYPE_STRING) {
94            char *stringValue = nullptr;
95            uint32_t valueLen = 0;
96            ret = OH_PreferencesValue_GetString(pValue, &stringValue, &valueLen);
97            if (ret == PREFERENCES_OK) {
98                // Service logic.
99                OH_Preferences_FreeString(stringValue);
100            }
101        } else {
102            // Invalid type.
103        }
104    }
105}
106
107// 1. Create a PreferencesOption instance.
108OH_PreferencesOption *option = OH_PreferencesOption_Create();
109if (option == nullptr) {
110    // Error handling.
111}
112// Set the file name.
113int ret = OH_PreferencesOption_SetFileName(option, "testdb");
114if (ret != PREFERENCES_OK) {
115    (void)OH_PreferencesOption_Destroy(option);
116    // Error handling.
117}
118// Set the application group ID.
119ret = OH_PreferencesOption_SetDataGroupId(option, "");
120if (ret != PREFERENCES_OK) {
121    (void)OH_PreferencesOption_Destroy(option);
122    // Error handling.
123}
124// Set the bundle name.
125ret = OH_PreferencesOption_SetBundleName(option, "com.example");
126if (ret != PREFERENCES_OK) {
127    (void)OH_PreferencesOption_Destroy(option);
128    // Error handling.
129}
130
131// Set the storage type for the PreferencesOption instance. Before the setting, call OH_Preferences_IsStorageTypeSupported to check whether the storage type is supported.
132bool isGskvSupported = false;
133ret = OH_Preferences_IsStorageTypeSupported(Preferences_StorageType::PREFERENCES_STORAGE_GSKV, &isGskvSupported);
134if (ret != PREFERENCES_OK) {
135    (void)OH_PreferencesOption_Destroy(option);
136    // Error handling.
137}
138if (isGskvSupported) {
139    ret = OH_PreferencesOption_SetStorageType(option, Preferences_StorageType::PREFERENCES_STORAGE_GSKV);
140    if (ret != PREFERENCES_OK) {
141        (void)OH_PreferencesOption_Destroy(option);
142        // Error handling.
143    }
144} else {
145    ret = OH_PreferencesOption_SetStorageType(option, Preferences_StorageType::PREFERENCES_STORAGE_XML);
146    if (ret != PREFERENCES_OK) {
147        (void)OH_PreferencesOption_Destroy(option);
148        // Error handling.
149    }
150}
151
152// 2. Open a Preferences instance.
153int errCode = PREFERENCES_OK;
154OH_Preferences *preference = OH_Preferences_Open(option, &errCode);
155// Destroy the PreferencesOption instance that is no longer used, and set the instance pointer to null.
156(void)OH_PreferencesOption_Destroy(option);
157option = nullptr;
158if (preference == nullptr || errCode != PREFERENCES_OK) {
159    // Error handling.
160}
161
162// 3. Subscribe to data changes of key_int, key_bool, and key_string.
163const char *keys[] = {"key_int", "key_bool", "key_string"};
164ret = OH_Preferences_RegisterDataObserver(preference, nullptr, DataChangeObserverCallback, keys, 3);
165if (ret != PREFERENCES_OK) {
166    (void)OH_Preferences_Close(preference);
167    // Error handling.
168}
169
170// 4. Set KV data in the Preferences instance.
171ret = OH_Preferences_SetInt(preference, keys[0], 0);
172if (ret != PREFERENCES_OK) {
173    (void)OH_Preferences_Close(preference);
174    // Error handling.
175}
176ret = OH_Preferences_SetBool(preference, keys[1], true);
177if (ret != PREFERENCES_OK) {
178    (void)OH_Preferences_Close(preference);
179    // Error handling.
180}
181ret = OH_Preferences_SetString(preference, keys[2], "string value");
182if (ret != PREFERENCES_OK) {
183    (void)OH_Preferences_Close(preference);
184    // Error handling.
185}
186
187// 5. Obtain KV data from the Preferences instance.
188int intValue = 0;
189ret = OH_Preferences_GetInt(preference, keys[0], &intValue);
190if (ret == PREFERENCES_OK) {
191    // Service logic.
192}
193
194bool boolValue = false;
195ret = OH_Preferences_GetBool(preference, keys[1], &boolValue);
196if (ret == PREFERENCES_OK) {
197    // Service logic.
198}
199
200char *stringValue = nullptr;
201uint32_t valueLen = 0;
202ret = OH_Preferences_GetString(preference, keys[2], &stringValue, &valueLen);
203if (ret == PREFERENCES_OK) {
204    // Service logic.
205    // Release the string obtained by OH_Preferences_GetString.
206    OH_Preferences_FreeString(stringValue);
207    stringValue = nullptr;
208}
209
210// 6. Close the Preferences instance and set the pointer to null.
211(void)OH_Preferences_Close(preference);
212preference = nullptr;
213
214```
215