• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# AppStorageV2: Storing Application-wide UI State
2
3To enhance the capability of the state management framework to store global UI status variables of applications, you are advised to use AppStorageV2.
4
5AppStorageV2 provides the capability of globally sharing state variables within an application. You can bind the same key through **connect** to share data across abilities.
6
7Before reading this topic, you are advised to read [\@ComponentV2](./arkts-new-componentV2.md), [\@ObservedV2 and \@Trace](./arkts-new-observedV2-and-trace.md), and API reference of [AppStorageV2](../reference/apis-arkui/js-apis-StateManagement.md#appstoragev2).
8
9>**NOTE**
10>
11>AppStorageV2 is supported since API version 12.
12>
13
14
15## Overview
16
17AppStorageV2 is a singleton to be created when the application UI is started. Its purpose is to provide central storage for application UI state attributes. And AppStorageV2 retains data during application running. Each attribute is accessed using a unique key, which is a string.
18
19UI components synchronize application state attributes with AppStorageV2. AppStorageV2 can be accessed during implementation of application service logic as well.
20
21AppStorageV2 supports state sharing among multiple UIAbility instances in the [main thread](../application-models/thread-model-stage.md) of an application.
22
23
24## How to Use
25
26### connect: Creating or Obtaining Stored Data
27
28```JavaScript
29static connect<T extends object>(
30    type: TypeConstructorWithArgs<T>,
31    keyOrDefaultCreator?: string | StorageDefaultCreator<T>,
32    defaultCreator?: StorageDefaultCreator<T>
33): T | undefined;
34```
35
36| connect      | Description                                                 |
37| ------------ | ----------------------------------------------------- |
38| Parameter        | **type**: specified type. If no **key** is specified, the name of the **type** is used as the **key**.<br> **keyOrDefaultCreator**: specified key or default constructor.<br> **defaultCreator**: default constructor.                                         |
39| Return value      | After creating or obtaining data, value is returned. Otherwise, **undefined** is returned.|
40
41>**NOTE**
42>
43>1. The third parameter is used when no **key** is specified or the second parameter is invalid, and the third parameter is used in all other cases.
44>
45>2. If the data has been stored in AppStorageV2, you can obtain the stored data without using the default constructor. If the data has not been stored, you must specify a default constructor; otherwise, an application exception will be thrown.
46>
47>3. Ensure that the data types match the key. Connecting different types of data to the same key will result in an application exception.
48>
49>4. You are advised to use meaningful values for keys. The values can contain letters, digits, and underscores (_) and a maximum of 255 characters. Using invalid characters or null characters will result in undefined behavior.
50>
51>5. When match the key with the [\@Observed](arkts-observed-and-objectlink.md) object, specify the key or customize the **name** attribute.
52
53### remove: Deleting the Stored Data of a Specified Key
54
55```JavaScript
56static remove<T>(keyOrType: string | TypeConstructorWithArgs<T>): void;
57```
58
59| remove       | Description                                                 |
60| ------------ | ----------------------------------------------------- |
61| Parameter        | **keyOrType**: key to be deleted. If the key is of the **Type**, the key to be deleted is the name of the **Type**.                                         |
62| Return value      | None.|
63
64>**NOTE**
65>
66>If a key that does not exist in AppStorageV2 is deleted, a warning is reported.
67
68### keys: Returning All Keys Stored in AppStorageV2
69
70```JavaScript
71static keys(): Array<string>;
72```
73
74| keys         | Description                                                 |
75| ------------ | ----------------------------------------------------- |
76| Parameter        | None.                                        |
77| Return value      | All keys stored in AppStorageV2.|
78
79
80## Constraints
81
821. This singleton must be used together with the UI thread only. Other threads, for example, @Sendable decorator is not supported.
83
842. Types such as collections.Set and collections.Map are not supported.
85
863. Non-buildin types, such as native PixelMap, NativePointer, and ArrayList types, are not supported.
87
88## Use Scenarios
89
90### Storing Data Between Two Pages
91
92Data page
93```ts
94// Data center
95// Sample.ets
96@ObservedV2
97export class Sample {
98  @Trace p1: number = 0;
99  p2: number = 10;
100}
101```
102
103Page 1
104```ts
105// Page1.ets
106import { AppStorageV2 } from '@kit.ArkUI';
107import { Sample } from '../Sample';
108
109@Entry
110@ComponentV2
111struct Page1 {
112  // Create a KV pair whose key is Sample in AppStorageV2 (if the key exists, the data in AppStorageV2 is returned) and associate it with prop.
113  @Local prop: Sample = AppStorageV2.connect(Sample, () => new Sample())!;
114  pageStack: NavPathStack = new NavPathStack();
115
116  build() {
117    Navigation(this.pageStack) {
118      Column() {
119        Button('Go to page2')
120          .onClick(() => {
121            this.pageStack.pushPathByName('Page2', null);
122          })
123
124        Button('Page1 connect the key Sample')
125          .onClick(() => {
126            // Create a KV pair whose key is Sample in AppStorageV2 (if the key exists, the data in AppStorageV2 is returned) and associate it with prop.
127            this.prop = AppStorageV2.connect(Sample, 'Sample', () => new Sample())!;
128          })
129
130        Button('Page1 remove the key Sample')
131          .onClick(() => {
132            // After being deleted from AppStorageV2, prop will no longer be associated with the value whose key is Sample.
133            AppStorageV2.remove(Sample);
134          })
135
136        Text(`Page1 add 1 to prop.p1: ${this.prop.p1}`)
137          .fontSize(30)
138          .onClick(() => {
139            this.prop.p1++;
140          })
141
142        Text(`Page1 add 1 to prop.p2: ${this.prop.p2}`)
143          .fontSize(30)
144          .onClick(() => {
145            // The page is not re-rendered, but the value of p2 is changed.
146            this.prop.p2++;
147          })
148
149        // Obtain all keys in the current AppStorageV2.
150        Text(`all keys in AppStorage: ${AppStorageV2.keys()}`)
151          .fontSize(30)
152      }
153    }
154  }
155}
156```
157
158Page 2
159```ts
160// Page2.ets
161import { AppStorageV2 } from '@kit.ArkUI';
162import { Sample } from '../Sample';
163
164@Builder
165export function Page2Builder() {
166  Page2()
167}
168
169@ComponentV2
170struct Page2 {
171  // Create a KV pair whose key is Sample in AppStorageV2 (if the key exists, the data in AppStorageV2 is returned) and associate it with prop.
172  @Local prop: Sample = AppStorageV2.connect(Sample, () => new Sample())!;
173  pathStack: NavPathStack = new NavPathStack();
174
175  build() {
176    NavDestination() {
177      Column() {
178        Button('Page2 connect the key Sample1')
179          .onClick(() => {
180            // Create a KV pair whose key is Sample1 in AppStorageV2 (if the key exists, the data in AppStorageV2 is returned) and associate it with prop.
181            this.prop = AppStorageV2.connect(Sample, 'Sample1', () => new Sample())!;
182          })
183
184        Text(`Page2 add 1 to prop.p1: ${this.prop.p1}`)
185          .fontSize(30)
186          .onClick(() => {
187            this.prop.p1++;
188          })
189
190        Text(`Page2 add 1 to prop.p2: ${this.prop.p2}`)
191          .fontSize(30)
192          .onClick(() => {
193            // The page is not re-rendered, but the value of p2 is changed, which is performed after re-initialization.
194            this.prop.p2++;
195          })
196
197        // Obtain all keys in the current AppStorageV2.
198        Text(`all keys in AppStorage: ${AppStorageV2.keys()}`)
199          .fontSize(30)
200      }
201    }
202    .onReady((context: NavDestinationContext) => {
203      this.pathStack = context.pathStack;
204    })
205  }
206}
207```
208When using **Navigation**, you need to add the **route_map.json** file to the **src/main/resources/base/profile** directory, replace the value of **pageSourceFile** with the path of **Page2**, and add **"routerMap": "$profile: route_map"** to the **module.json5** file.
209```json
210{
211  "routerMap": [
212    {
213      "name": "Page2",
214      "pageSourceFile": "src/main/ets/pages/Page2.ets",
215      "buildFunction": "Page2Builder",
216      "data": {
217        "description" : "AppStorageV2 example"
218      }
219    }
220  ]
221}
222```
223