data-persistence-by-preferences.md 9.7 KB
Newer Older
A
Annie_wang 已提交
1 2 3 4 5 6 7 8 9 10 11 12
# Persisting Preferences Data


## When to Use

The **Preferences** module provides APIs for processing data in the form of key-value (KV) pairs, and supports persistence of the KV pairs when required, as well as modification and query of the data. You can use **Preferences** when you want a unique storage for global data. **Preferences** caches data in the memory, which allows fast access when the data is required. **Preferences** is recommended for storing small amount of data, such as personalized settings (font size and whether to enable the night mode) of applications.


## Working Principles

User applications call **Preference** through the JS interface to read and write data files. You can load the data of a **Preferences** persistence file to a **Preferences** instance. Each file uniquely corresponds to an instance. The system stores the instance in memory through a static container until the instance is removed from the memory or the file is deleted. The following figure illustrates how **Preference** works.

A
Annie_wang 已提交
13
The preference persistent file of an application is stored in the application sandbox. You can use **context** to obtain the file path. For details, see [Obtaining Application File Paths](../application-models/application-context-stage.md#obtaining-application-file-paths).
A
Annie_wang 已提交
14 15

**Figure 1** Preferences working mechanism 
A
Annie_wang 已提交
16 17 18 19 20 21 22 23

![preferences](figures/preferences.jpg)


## Constraints

- The key in a KV pair must be a string and cannot be empty or exceed 80 bytes.

A
Annie_wang 已提交
24
- If the value is of the string type, use the UTF-8 encoding format. It can be empty or a string not longer than 8192 bytes.
A
Annie_wang 已提交
25 26 27 28 29 30

- The memory usage increases with the amount of **Preferences** data. The maximum number of data records recommended is 10,000. Otherwise, high memory overheads will be caused.


## Available APIs

A
Annie_wang 已提交
31
The following table lists the APIs used for persisting user preference data. For more information about the APIs, see [User Preferences](../reference/apis/js-apis-data-preferences.md).
A
Annie_wang 已提交
32

A
Annie_wang 已提交
33 34 35 36 37 38 39 40 41 42 43
| API                                                          | Description                                                  |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| getPreferences(context: Context, name: string, callback: AsyncCallback<Preferences>): void | Obtains a **Preferences** instance.                          |
| putSync(key: string, value: ValueType): void                 | Writes data to the Preferences instance. You can use **flush()** to persist the **Preferences** instance data. An asynchronous API is also provided. |
| hasSync(key: string): void                                   | Checks whether the **Preferences** instance contains a KV pair with the given key. The key cannot be empty. An asynchronous API is also provided. |
| getSync(key: string, defValue: ValueType): void              | Obtains the value of the specified key. If the value is null or not of the default value type, **defValue** is returned. An asynchronous API is also provided. |
| deleteSync(key: string): void                                | Deletes the KV pair with the given key from the **Preferences** instance. An asynchronous API is also provided. |
| flush(callback: AsyncCallback<void>): void             | Flushes the data of this **Preferences** instance to a file for data persistence. |
| on(type: 'change', callback: Callback<{ key : string }>): void | Subscribes to data changes of the specified key. When the value of the specified key is changed and saved by **flush()**, a callback will be invoked to return the new data. |
| off(type: 'change', callback?: Callback<{ key : string }>): void | Unsubscribes from data changes.                              |
| deletePreferences(context: Context, name: string, callback: AsyncCallback<void>): void | Deletes a **Preferences** instance from memory. If the **Preferences** instance has a persistent file, this API also deletes the persistent file. |
A
Annie_wang 已提交
44 45 46 47 48


## How to Develop

1. Import the **@ohos.data.preferences** module.
A
Annie_wang 已提交
49
   
A
Annie_wang 已提交
50 51 52 53 54 55 56 57
   ```js
   import dataPreferences from '@ohos.data.preferences';
   ```

2. Obtain a **Preferences** instance. Read data from a file and load the data to a **Preferences** instance for data operations.

   Stage model:

A
Annie_wang 已提交
58
   
A
Annie_wang 已提交
59 60
   ```js
   import UIAbility from '@ohos.app.ability.UIAbility';
A
Annie_wang 已提交
61 62
   import { BusinessError } from '@ohos.base';
   import window from '@ohos.window';
A
Annie_wang 已提交
63 64
   
   class EntryAbility extends UIAbility {
A
Annie_wang 已提交
65
     onWindowStageCreate(windowStage: window.WindowStage) {
A
Annie_wang 已提交
66
       try {
A
Annie_wang 已提交
67
         dataPreferences.getPreferences(this.context, 'myStore', (err: BusinessError, preferences: dataPreferences.Preferences) => {
A
Annie_wang 已提交
68 69 70 71 72
           if (err) {
             console.error(`Failed to get preferences. Code:${err.code},message:${err.message}`);
             return;
           }
           console.info('Succeeded in getting preferences.');
A
Annie_wang 已提交
73
           // Before performing related data operations, obtain a Preferences instance.
A
Annie_wang 已提交
74 75 76 77 78 79 80 81 82 83
         })
       } catch (err) {
         console.error(`Failed to get preferences. Code:${err.code},message:${err.message}`);
       }
     }
   }
   ```

   FA model:

A
Annie_wang 已提交
84
   
A
Annie_wang 已提交
85 86
   ```js
   import featureAbility from '@ohos.ability.featureAbility';
A
Annie_wang 已提交
87
   import { BusinessError } from '@ohos.base';
A
Annie_wang 已提交
88 89 90 91 92
   
   // Obtain the context.
   let context = featureAbility.getContext();
   
   try {
A
Annie_wang 已提交
93
     dataPreferences.getPreferences(this.context, 'myStore', (err: BusinessError, preferences: dataPreferences.Preferences) => {
A
Annie_wang 已提交
94 95 96 97 98
       if (err) {
         console.error(`Failed to get preferences. Code:${err.code},message:${err.message}`);
         return;
       }
       console.info('Succeeded in getting preferences.');
A
Annie_wang 已提交
99
       // Before performing related data operations, obtain a Preferences instance.
A
Annie_wang 已提交
100 101 102 103 104 105 106 107
     })
   } catch (err) {
     console.error(`Failed to get preferences. Code is ${err.code},message:${err.message}`);
   }
   ```

3. Write data.

A
Annie_wang 已提交
108
   Use **putSync()** to save data to the cached **Preferences** instance. After data is written, you can use **flush()** to persist the **Preferences** instance data to a file if necessary.
A
Annie_wang 已提交
109 110 111

   > **NOTE**
   >
A
Annie_wang 已提交
112
   > If the specified key already exists, the **putSync()** method changes the value. You can use **hasSync()** to check whether the KV pair exists.
A
Annie_wang 已提交
113 114 115

   Example:

A
Annie_wang 已提交
116
   
A
Annie_wang 已提交
117 118
   ```js
   try {
A
Annie_wang 已提交
119 120 121 122 123 124 125
     if (preferences.hasSync('startup')) {
       console.info("The key 'startup' is contained.");
     } else {
       console.info("The key 'startup' does not contain.");
       // Add a KV pair.
       preferences.putSync('startup', 'auto');
     }
A
Annie_wang 已提交
126 127 128 129 130 131 132
   } catch (err) {
     console.error(`Failed to check the key 'startup'. Code:${err.code}, message:${err.message}`);
   }
   ```

4. Read data.

A
Annie_wang 已提交
133
     Use **getSync()** to obtain the value of the specified key. If the value is null or is not of the default value type, the default data is returned. Example:
A
Annie_wang 已提交
134 135 136
     
   ```js
   try {
A
Annie_wang 已提交
137 138
     let val = preferences.getSync('startup', 'default');
     console.info(`Succeeded in getting value of 'startup'. val: ${val}.`);
A
Annie_wang 已提交
139 140 141 142 143
   } catch (err) {
     console.error(`Failed to get value of 'startup'. Code:${err.code}, message:${err.message}`);
   }
   ```

A
Annie_wang 已提交
144
5. Delete data.
A
Annie_wang 已提交
145

A
Annie_wang 已提交
146
   Use **deleteSync()** to delete a KV pair.<br>Example:
A
Annie_wang 已提交
147

A
Annie_wang 已提交
148
   
A
Annie_wang 已提交
149 150
   ```js
   try {
A
Annie_wang 已提交
151
     preferences.deleteSync('startup');
A
Annie_wang 已提交
152 153 154 155 156 157 158 159 160 161 162
   } catch (err) {
     console.error(`Failed to delete the key 'startup'. Code:${err.code}, message:${err.message}`);
   }
   ```

6. Persist data.

     You can use **flush()** to persist the data held in a **Preferences** instance to a file. Example:
     
   ```js
   try {
A
Annie_wang 已提交
163
     preferences.flush((err: BusinessError) => {
A
Annie_wang 已提交
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
       if (err) {
         console.error(`Failed to flush. Code:${err.code}, message:${err.message}`);
         return;
       }
       console.info('Succeeded in flushing.');
     })
   } catch (err) {
     console.error(`Failed to flush. Code:${err.code}, message:${err.message}`);
   }
   ```

7. Subscribe to data changes.

     Specify an observer as the callback to return the data changes for an application. When the value of the subscribed key is changed and saved by **flush()**, the observer callback will be invoked to return the new data. Example:
     
   ```js
A
Annie_wang 已提交
180 181
   interface observer {
      key: string
A
Annie_wang 已提交
182
   }
A
Annie_wang 已提交
183 184 185
   preferences.on('change', (key: observer) => {
     console.info('The key' + key + 'changed.');
   });
A
Annie_wang 已提交
186
   // The data is changed from 'auto' to 'manual'.
A
Annie_wang 已提交
187
   preferences.put('startup', 'manual', (err: BusinessError) => {
A
Annie_wang 已提交
188 189 190 191 192
     if (err) {
       console.error(`Failed to put the value of 'startup'. Code:${err.code},message:${err.message}`);
       return;
     }
     console.info("Succeeded in putting the value of 'startup'.");
A
Annie_wang 已提交
193
     preferences.flush((err: BusinessError) => {
A
Annie_wang 已提交
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
       if (err) {
         console.error(`Failed to flush. Code:${err.code}, message:${err.message}`);
         return;
       }
       console.info('Succeeded in flushing.');
     })
   })
   ```

8. Delete a **Preferences** instance from the memory.

   Use **deletePreferences()** to delete a **Preferences** instance from the memory. If the **Preferences** instance has a persistent file, the persistent file and its backup and corrupted files will also be deleted.

   > **NOTE**
   >
   > - The deleted **Preferences** instance cannot be used for data operations. Otherwise, data inconsistency will be caused.
   > 
   > - The deleted data and files cannot be restored.

   Example:

A
Annie_wang 已提交
215
   
A
Annie_wang 已提交
216 217
   ```js
   try {
A
Annie_wang 已提交
218
     dataPreferences.deletePreferences(this.context, 'myStore', (err: BusinessError) => {
A
Annie_wang 已提交
219 220 221 222 223 224 225 226 227
       if (err) {
         console.error(`Failed to delete preferences. Code:${err.code}, message:${err.message}`);
         return;
       }
       console.info('Succeeded in deleting preferences.');
     })
   } catch (err) {
     console.error(`Failed to delete preferences. Code:${err.code}, message:${err.message}`);
   }
A
Annie_wang 已提交
228
   ```