• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Context (Stage Model)
2
3
4## Overview
5
6[Context](../reference/apis-ability-kit/js-apis-inner-application-context.md) is the context of an object in an application. It provides basic information about the application, for example, [resourceManager](../reference/apis-localization-kit/js-apis-resource-manager.md), [applicationInfo](../reference/apis-ability-kit/js-apis-bundleManager-applicationInfo.md), [dir](../reference/apis-ability-kit/js-apis-inner-application-context.md#properties) (application file path), and [area](../reference/apis-ability-kit/js-apis-app-ability-contextConstant.md#areamode) (encryption level). It also provides basic methods such as **createBundleContext()** and [getApplicationContext()](../reference/apis-ability-kit/js-apis-inner-application-context.md#contextgetapplicationcontext). The [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md) component and [ExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-extensionAbility.md) derived class components have their own **Context** classes, for example, the base class **Context**, [ApplicationContext](../reference/apis-ability-kit/js-apis-inner-application-applicationContext.md), [AbilityStageContext](../reference/apis-ability-kit/js-apis-inner-application-abilityStageContext.md), [UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md), [ExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-extensionContext.md), and ServiceExtensionContext.
7
8- The figure below illustrates the inheritance relationship of contexts.
9
10  ![context-inheritance](figures/context-inheritance.png)
11
12- The figure below illustrates the holding relationship of contexts.
13
14  ![context-holding](figures/context-holding.png)
15
16- The following describes the information provided by different contexts.
17  - [UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md): Each [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md) has the **Context** attribute, which provides APIs to operate an application component, obtain the application component configuration, and more.
18
19    ```ts
20    import { UIAbility, AbilityConstant, Want } from '@kit.AbilityKit';
21
22    export default class EntryAbility extends UIAbility {
23      onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
24        let uiAbilityContext = this.context;
25        //...
26      }
27    }
28    ```
29
30     > **NOTE**
31     >
32     > For details about how to obtain the context of a **UIAbility** instance on the page, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability).
33  - Scenario-specific [ExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-extensionContext.md): For example, ServiceExtensionContext, inherited from ExtensionContext, provides APIs related to background services.
34
35    ```ts
36    import { ServiceExtensionAbility, Want } from '@kit.AbilityKit';
37
38    export default class ServiceExtAbility extends ServiceExtensionAbility {
39      onCreate(want: Want) {
40        let serviceExtensionContext = this.context;
41        //...
42      }
43    }
44    ```
45  - [AbilityStageContext](../reference/apis-ability-kit/js-apis-inner-application-abilityStageContext.md): module-level context. It provides [HapModuleInfo](../reference/apis-ability-kit/js-apis-inner-application-abilityStageContext.md#properties) and [Configuration](../reference/apis-ability-kit/js-apis-inner-application-abilityStageContext.md#properties) in addition to those provided by the base class **Context**.
46
47    ```ts
48    import { AbilityStage } from '@kit.AbilityKit';
49
50    export default class MyAbilityStage extends AbilityStage {
51      onCreate(): void {
52        let abilityStageContext = this.context;
53        //...
54      }
55    }
56    ```
57  - [ApplicationContext](../reference/apis-ability-kit/js-apis-inner-application-applicationContext.md): application-level context. It provides APIs for subscribing to application component lifecycle changes, system memory changes, and system environment changes, setting the application language and color mode, clearing application data, and revoking permissions requested from users. It can be obtained from [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md), [ExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-extensionAbility.md), and [AbilityStage](../reference/apis-ability-kit/js-apis-app-ability-abilityStage.md).
58
59    ```ts
60    import { UIAbility, AbilityConstant, Want } from '@kit.AbilityKit';
61
62    export default class EntryAbility extends UIAbility {
63      onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
64        let applicationContext = this.context.getApplicationContext();
65        //...
66      }
67    }
68    ```
69
70
71## Typical Usage Scenarios of Context
72
73
74This topic describes how to use the context in the following scenarios:
75
76- [Obtaining Application File Paths](#obtaining-application-file-paths)
77- [Obtaining and Modifying Encryption Levels](#obtaining-and-modifying-encryption-levels)
78- [Obtaining the Context of Other Modules in the Current Application](#obtaining-the-context-of-other-modules-in-the-current-application)
79- [Subscribing to UIAbility Lifecycle Changes in a Process](#subscribing-to-uiability-lifecycle-changes-in-a-process)
80
81
82### Obtaining Application File Paths
83
84The [base class Context](../reference/apis-ability-kit/js-apis-inner-application-context.md) provides the capability of obtaining application file paths. [ApplicationContext](../reference/apis-ability-kit/js-apis-inner-application-applicationContext.md), [AbilityStageContext](../reference/apis-ability-kit/js-apis-inner-application-abilityStageContext.md), [UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md), and [ExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-extensionContext.md) inherit this capability. However, the specific paths retrieved can differ based on the type of the context used.
85
86- [ApplicationContext](../reference/apis-ability-kit/js-apis-inner-application-applicationContext.md): This context provides access to the application-level file path, which is used to store global application information. Files in this path are removed when the application is uninstalled.
87- [AbilityStageContext](../reference/apis-ability-kit/js-apis-inner-application-abilityStageContext.md), [UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md), and [ExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-extensionContext.md): These contexts provide access to [module-level](../quick-start/application-package-overview.md) file paths. Files in these paths are removed when the corresponding [HAP](../quick-start/hap-package.md) or [HSP](../quick-start/in-app-hsp.md) module is uninstalled. Uninstalling an HAP or HSP module does not affect files under the application-level path unless all HAP and HSP modules of the application are uninstalled.
88
89  - UIAbilityContext: This context can be used to obtain the file paths of the module containing the UIAbility.
90  - ExtensionContext: This context can be used to obtain the file paths of the module containing the ExtensionAbility.
91  - AbilityStageContext: Given that AbilityStageContext is initialized earlier than UIAbilityContext and ExtensionContext, it is typically used to obtain file paths within the AbilityStage.
92
93>**NOTE**
94>
95> The application file paths are a type of application sandbox paths. For details, see [Application Sandbox Directory](../file-management/app-sandbox-directory.md).
96
97**Table 1** Description of application file paths obtained by different types of contexts
98| Name| Description| Path Obtained by ApplicationContext| Path Obtained by AbilityStageContext, UIAbilityContext, and ExtensionContext|
99| -------- | -------- | -------- | -------- |
100| bundleCodeDir | Bundle code directory.| \<Path prefix>/el1/bundle| \<Path prefix>/el1/bundle|
101| cacheDir | Cache directory.| \<Path prefix>/\<Encryption level>/base/cache| \<Path prefix>/\<Encryption level>/base/**haps/\<module-name>**/cache|
102| filesDir | File directory.| \<Path prefix>/\<Encryption level>/base/files| \<Path prefix>/\<Encryption level>/base/**haps/\<module-name>**/files|
103| preferencesDir | Preferences directory.| \<Path prefix>/\<Encryption level>/base/preferences| \<Path prefix>/\<Encryption level>/base/**haps/\<module-name>**/preferences|
104| tempDir | Temporary directory.| \<Path prefix>/\<Encryption level>/base/temp| \<Path prefix>/\<Encryption level>/base/**haps/\<module-name>**/temp|
105| databaseDir | Database directory.| \<Path prefix>/\<Encryption level>/database| \<Path prefix>/\<Encryption level>/database/**\<module-name>**|
106| distributedFilesDir | Distributed file directory.| \<Path prefix>/el2/distributedFiles| \<Path prefix>/el2/distributedFiles/|
107| resourceDir<sup>11+<sup> | Resource directory.<br>**NOTE**<br> You are required to manually create the **resfile** directory in **\<module-name>\resource**.| N/A| \<Path prefix>/el1/bundle/**\<module-name>**/resources/resfile|
108| cloudFileDir<sup>12+</sup> | Cloud file directory.| \<Path prefix>/el2/cloud| \<Path prefix>/el2/cloud/|
109
110This section uses ApplicationContext as an example to describe how to obtain the application file path, create a file in the path, and read and write the file. The sample code is as follows:
111
112  ```ts
113  import { common } from '@kit.AbilityKit';
114  import { buffer } from '@kit.ArkTS';
115  import { fileIo, ReadOptions } from '@kit.CoreFileKit';
116  import { hilog } from '@kit.PerformanceAnalysisKit';
117
118  const TAG: string = '[Page_Context]';
119  const DOMAIN_NUMBER: number = 0xFF00;
120
121  @Entry
122  @Component
123  struct Index {
124    @State message: string = 'Hello World';
125    private context = getContext(this) as common.UIAbilityContext;
126
127    build() {
128      Row() {
129        Column() {
130          Text(this.message)
131          // ...
132          Button() {
133            Text('create file')
134              // ...
135              .onClick(() => {
136                let applicationContext = this.context.getApplicationContext();
137                // Obtain the application file path.
138                let filesDir = applicationContext.filesDir;
139                hilog.info(DOMAIN_NUMBER, TAG, `filePath: ${filesDir}`);
140                // Create and open the file if it does not exist. Open the file if it already exists.
141                let file = fileIo.openSync(filesDir + '/test.txt', fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
142                // Write data to the file.
143                let writeLen = fileIo.writeSync(file.fd, "Try to write str.");
144                hilog.info(DOMAIN_NUMBER, TAG, `The length of str is: ${writeLen}`);
145                // Create an ArrayBuffer object with a size of 1024 bytes to store the data read from the file.
146                let arrayBuffer = new ArrayBuffer(1024);
147                // Set the offset and length to read.
148                let readOptions: ReadOptions = {
149                  offset: 0,
150                  length: arrayBuffer.byteLength
151                };
152                // Read the file content to the ArrayBuffer object and return the number of bytes that are actually read.
153                let readLen = fileIo.readSync(file.fd, arrayBuffer, readOptions);
154                // Convert the ArrayBuffer object into a Buffer object and output it as a string.
155                let buf = buffer.from(arrayBuffer, 0, readLen);
156                hilog.info(DOMAIN_NUMBER, TAG, `the content of file: ${buf.toString()}`);
157                // Close the file.
158                fileIo.closeSync(file);
159              })
160          }
161          // ...
162        }
163        // ...
164      }
165      // ...
166    }
167  }
168  ```
169
170
171### Obtaining and Modifying Encryption Levels
172
173Encrypting application files enhances data security by preventing files from unauthorized access. Different application files require different levels of protection.
174
175In practice, you need to select a proper encryption level based on scenario-specific requirements to protect application data security.  For details about the permissions required for a specific encryption level, see [AreaMode](../reference/apis-ability-kit/js-apis-app-ability-contextConstant.md#areamode) in [ContextConstant](../reference/apis-ability-kit/js-apis-app-ability-contextConstant.md).
176
177- EL1: For private files, such as alarms and wallpapers, the application can place them in a directory with the device-level encryption (EL1) to ensure that they can be accessed before the user enters the password.
178- EL2: For sensitive files, such as personal privacy data, the application can place them in a directory with the user-level encryption (EL2).
179- EL3: For step recording, file download, or music playback that needs to read, write, and create files when the screen is locked, the application can place these files in EL3.
180- EL4: For files that are related to user security information and do not need to be read, written, or created when the screen is locked, the application can place them in EL4.
181- EL5: By default, sensitive user privacy files cannot be read or written on the lock screen. If such files need to be read or written on the lock screen, you can call [Access](../reference/apis-ability-kit/js-apis-screenLockFileManager.md#screenlockfilemanageracquireaccess) to apply for reading or writing files before the screen is locked or create new files that can be read and written after the screen is locked. It is more appropriate to place these files in EL5.
182
183You can obtain and set the encryption level by reading and writing the **area** attribute in [Context](../reference/apis-ability-kit/js-apis-inner-application-context.md).
184
185```ts
186// EntryAbility.ets
187import { UIAbility, contextConstant, AbilityConstant, Want } from '@kit.AbilityKit';
188
189export default class EntryAbility extends UIAbility {
190  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
191    // Before storing common information, switch the encryption level to EL1.
192    this.context.area = contextConstant.AreaMode.EL1; // Change the encryption level.
193    // Store common information.
194
195    // Before storing sensitive information, switch the encryption level to EL2.
196    this.context.area = contextConstant.AreaMode.EL2; // Change the encryption level.
197    // Store sensitive information.
198
199    // Before storing sensitive information, switch the encryption level to EL3.
200    this.context.area = contextConstant.AreaMode.EL3; // Change the encryption level.
201    // Store sensitive information.
202
203    // Before storing sensitive information, switch the encryption level to EL4.
204    this.context.area = contextConstant.AreaMode.EL4; // Change the encryption level.
205    // Store sensitive information.
206
207    // Before storing sensitive information, switch the encryption level to EL5.
208    this.context.area = contextConstant.AreaMode.EL5; // Change the encryption level.
209    // Store sensitive information.
210  }
211}
212```
213```ts
214// Index.ets
215import { contextConstant, common } from '@kit.AbilityKit';
216import { promptAction } from '@kit.ArkUI';
217
218@Entry
219@Component
220struct Page_Context {
221  private context = getContext(this) as common.UIAbilityContext;
222
223  build() {
224    Column() {
225      //...
226      List({ initialIndex: 0 }) {
227        //...
228        ListItem() {
229          Row() {
230            //...
231          }
232          .onClick(() => {
233            // Before storing common information, switch the encryption level to EL1.
234            if (this.context.area === contextConstant.AreaMode.EL2) { // Obtain the area.
235              this.context.area = contextConstant.AreaMode.EL1; // Modify the area.
236              promptAction.showToast({
237                message: 'SwitchToEL1'
238              });
239            }
240            // Store common information.
241          })
242        }
243        //...
244        ListItem() {
245          Row() {
246            //...
247          }
248          .onClick(() => {
249            // Before storing sensitive information, switch the encryption level to EL2.
250            if (this.context.area === contextConstant.AreaMode.EL1) { // Obtain the area.
251              this.context.area = contextConstant.AreaMode.EL2; // Modify the area.
252              promptAction.showToast({
253                message: 'SwitchToEL2'
254              });
255            }
256            // Store sensitive information.
257          })
258        }
259        //...
260      }
261      //...
262    }
263    //...
264  }
265}
266```
267
268
269### Obtaining the Context of Other Modules in the Current Application
270
271Call [createModuleContext(context: Context, moduleName: string)](../reference/apis-ability-kit/js-apis-app-ability-application.md#applicationcreatemodulecontext12) to obtain the context of another module in the current application. After obtaining the context, you can obtain the resource information of that module.
272
273  ```ts
274  import { common, application } from '@kit.AbilityKit';
275  import { promptAction } from '@kit.ArkUI';
276  import { BusinessError } from '@kit.BasicServicesKit';
277
278  let storageEventCall = new LocalStorage();
279
280  @Entry(storageEventCall)
281  @Component
282  struct Page_Context {
283    private context = getContext(this) as common.UIAbilityContext;
284
285    build() {
286      Column() {
287        //...
288        List({ initialIndex: 0 }) {
289          ListItem() {
290            Row() {
291              //...
292            }
293            .onClick(() => {
294              let moduleName2: string = 'entry';
295              application.createModuleContext(this.context, moduleName2)
296                .then((data: common.Context) => {
297                  console.info(`CreateModuleContext success, data: ${JSON.stringify(data)}`);
298                  if (data !== null) {
299                    promptAction.showToast({
300                      message: ('Context obtained')
301                    });
302                  }
303                })
304                .catch((err: BusinessError) => {
305                  console.error(`CreateModuleContext failed, err code:${err.code}, err msg: ${err.message}`);
306                });
307            })
308          }
309          //...
310        }
311        //...
312      }
313      //...
314    }
315  }
316  ```
317
318
319### Subscribing to UIAbility Lifecycle Changes in a Process
320
321In the DFX statistics scenario of an application, if you need to collect statistics on the stay duration and access frequency of a page, you can subscribe to [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md) lifecycle changes in a process.
322
323[ApplicationContext](../reference/apis-ability-kit/js-apis-inner-application-applicationContext.md) provides APIs for subscribing to UIAbility lifecycle changes in a process. When the UIAbility lifecycle changes in a process, for example, being created or destroyed, becoming visible or invisible, or gaining or losing focus, the corresponding callback is triggered. Each time the callback is registered, a listener lifecycle ID is returned, with the value incremented by 1 each time. When the number of listeners exceeds the upper limit (2^63-1), **-1** is returned. The following uses [UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md) as an example.
324
325
326```ts
327import { AbilityConstant, AbilityLifecycleCallback, UIAbility, Want } from '@kit.AbilityKit';
328import { hilog } from '@kit.PerformanceAnalysisKit';
329import { window } from '@kit.ArkUI';
330import  { BusinessError } from '@kit.BasicServicesKit';
331
332const TAG: string = '[LifecycleAbility]';
333const DOMAIN_NUMBER: number = 0xFF00;
334
335export default class LifecycleAbility extends UIAbility {
336  // Define a lifecycle ID.
337  lifecycleId: number = -1;
338
339  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
340    // Define a lifecycle callback object.
341    let abilityLifecycleCallback: AbilityLifecycleCallback = {
342      // Called when a UIAbility is created.
343      onAbilityCreate(uiAbility) {
344        hilog.info(DOMAIN_NUMBER, TAG, `onAbilityCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
345      },
346      // Called when a window is created.
347      onWindowStageCreate(uiAbility, windowStage: window.WindowStage) {
348        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
349        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageCreate windowStage: ${JSON.stringify(windowStage)}`);
350      },
351      // Called when the window becomes active.
352      onWindowStageActive(uiAbility, windowStage: window.WindowStage) {
353        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageActive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
354        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageActive windowStage: ${JSON.stringify(windowStage)}`);
355      },
356      // Called when the window becomes inactive.
357      onWindowStageInactive(uiAbility, windowStage: window.WindowStage) {
358        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageInactive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
359        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageInactive windowStage: ${JSON.stringify(windowStage)}`);
360      },
361      // Called when the window is destroyed.
362      onWindowStageDestroy(uiAbility, windowStage: window.WindowStage) {
363        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
364        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageDestroy windowStage: ${JSON.stringify(windowStage)}`);
365      },
366      // Called when the UIAbility is destroyed.
367      onAbilityDestroy(uiAbility) {
368        hilog.info(DOMAIN_NUMBER, TAG, `onAbilityDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
369      },
370      // Called when the UIAbility is switched from the background to the foreground.
371      onAbilityForeground(uiAbility) {
372        hilog.info(DOMAIN_NUMBER, TAG, `onAbilityForeground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
373      },
374      // Called when the UIAbility is switched from the foreground to the background.
375      onAbilityBackground(uiAbility) {
376        hilog.info(DOMAIN_NUMBER, TAG, `onAbilityBackground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
377      },
378      // Called when UIAbility is continued on another device.
379      onAbilityContinue(uiAbility) {
380        hilog.info(DOMAIN_NUMBER, TAG, `onAbilityContinue uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
381      }
382    };
383    // Obtain the application context.
384    let applicationContext = this.context.getApplicationContext();
385    try {
386      // Register the application lifecycle callback.
387      this.lifecycleId = applicationContext.on('abilityLifecycle', abilityLifecycleCallback);
388    } catch (err) {
389      let code = (err as BusinessError).code;
390      let message = (err as BusinessError).message;
391      hilog.error(DOMAIN_NUMBER, TAG, `Failed to register applicationContext. Code is ${code}, message is ${message}`);
392    }
393
394    hilog.info(DOMAIN_NUMBER, TAG, `register callback number: ${this.lifecycleId}`);
395  }
396  //...
397  onDestroy(): void {
398    // Obtain the application context.
399    let applicationContext = this.context.getApplicationContext();
400    try {
401      // Deregister the application lifecycle callback.
402      applicationContext.off('abilityLifecycle', this.lifecycleId);
403    } catch (err) {
404      let code = (err as BusinessError).code;
405      let message = (err as BusinessError).message;
406      hilog.error(DOMAIN_NUMBER, TAG, `Failed to unregister applicationContext. Code is ${code}, message is ${message}`);
407    }
408  }
409}
410```
411