• 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. The application file paths are a type of application sandbox paths. For details, see [Application Sandbox Directory](../file-management/app-sandbox-directory.md).
85
86The application file paths obtained by the preceding contexts are different.
87
88- The application file path obtained through [ApplicationContext](../reference/apis-ability-kit/js-apis-inner-application-applicationContext.md) is at the application level. This path is recommended for storing global application information, and the files in the path will be deleted when the application is uninstalled.
89
90  | Name| Path|
91  | -------- | -------- |
92  | bundleCodeDir | \<Path prefix>/el1/bundle|
93  | cacheDir | \<Path prefix>/\<Encryption level>/base/cache|
94  | filesDir | \<Path prefix>/\<Encryption level>/base/files|
95  | preferencesDir | \<Path prefix>/\<Encryption level>/base/preferences|
96  | tempDir | \<Path prefix>/\<Encryption level>/base/temp|
97  | databaseDir | \<Path prefix>/\<Encryption level>/database|
98  | distributedFilesDir | \<Path prefix>/el2/distributedFiles|
99  | cloudFileDir<sup>12+</sup> | \<Path prefix>/el2/cloud|
100
101  The sample code is as follows:
102
103  ```ts
104  import { common } from '@kit.AbilityKit';
105  import { hilog } from '@kit.PerformanceAnalysisKit';
106  import { promptAction } from '@kit.ArkUI';
107
108  const TAG: string = '[Page_Context]';
109  const DOMAIN_NUMBER: number = 0xFF00;
110
111  @Entry
112  @Component
113  struct Page_Context {
114    private context = getContext(this) as common.UIAbilityContext;
115
116    build() {
117      Column() {
118        //...
119        List({ initialIndex: 0 }) {
120          ListItem() {
121            Row() {
122              //...
123            }
124            .onClick(() => {
125              let applicationContext = this.context.getApplicationContext();
126              let cacheDir = applicationContext.cacheDir;
127              let tempDir = applicationContext.tempDir;
128              let filesDir = applicationContext.filesDir;
129              let databaseDir = applicationContext.databaseDir;
130              let bundleCodeDir = applicationContext.bundleCodeDir;
131              let distributedFilesDir = applicationContext.distributedFilesDir;
132              let preferencesDir = applicationContext.preferencesDir;
133              let cloudFileDir = applicationContext.cloudFileDir;
134              // Obtain the application file path.
135              let filePath = tempDir + 'test.txt';
136              hilog.info(DOMAIN_NUMBER, TAG, `filePath: ${filePath}`);
137              if (filePath !== null) {
138                promptAction.showToast({
139                  message: filePath
140                });
141              }
142            })
143          }
144          //...
145        }
146        //...
147      }
148      //...
149    }
150  }
151  ```
152
153- The application file path obtained through [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) is at the [HAP](../quick-start/hap-package.md) level. This path is recommended for storing HAP-related information, and the files in this path are deleted when the HAP is uninstalled. However, the deletion does not affect the files in the application-level path unless all HAPs of the application are uninstalled.
154
155  | Name| Path|
156  | -------- | -------- |
157  | bundleCodeDir | \<Path prefix>/el1/bundle|
158  | cacheDir | \<Path prefix>/\<Encryption level>/base/**haps/\<module-name>**/cache|
159  | filesDir | \<Path prefix>/\<Encryption level>/base/**haps/\<module-name>**/files|
160  | preferencesDir | \<Path prefix>/\<Encryption level>/base/**haps/\<module-name>**/preferences|
161  | tempDir | \<Path prefix>/\<Encryption level>/base/**haps/\<module-name>**/temp|
162  | databaseDir | \<Path prefix>/\<Encryption level>/database/**\<module-name>**|
163  | distributedFilesDir | \<Path prefix>/el2/distributedFiles/**\<module-name>**|
164  | cloudFileDir<sup>12+</sup> | \<Path prefix>/el2/cloud/**\<module-name>**|
165
166  The sample code is as follows:
167
168  ```ts
169  import { common } from '@kit.AbilityKit';
170  import { hilog } from '@kit.PerformanceAnalysisKit';
171  import { promptAction } from '@kit.ArkUI';
172
173  const TAG: string = '[Page_Context]';
174  const DOMAIN_NUMBER: number = 0xFF00;
175
176  @Entry
177  @Component
178  struct Page_Context {
179    private context = getContext(this) as common.UIAbilityContext;
180
181    build() {
182      Column() {
183        //...
184        List({ initialIndex: 0 }) {
185          ListItem() {
186            Row() {
187              //...
188            }
189            .onClick(() => {
190              let cacheDir = this.context.cacheDir;
191              let tempDir = this.context.tempDir;
192              let filesDir = this.context.filesDir;
193              let databaseDir = this.context.databaseDir;
194              let bundleCodeDir = this.context.bundleCodeDir;
195              let distributedFilesDir = this.context.distributedFilesDir;
196              let preferencesDir = this.context.preferencesDir;
197              let cloudFileDir = applicationContext.cloudFileDir;
198              // Obtain the application file path.
199              let filePath = tempDir + 'test.txt';
200              hilog.info(DOMAIN_NUMBER, TAG, `filePath: ${filePath}`);
201              if (filePath !== null) {
202                promptAction.showToast({
203                  message: filePath
204                });
205              }
206            })
207          }
208          //...
209        }
210        //...
211      }
212      //...
213    }
214  }
215  ```
216
217
218### Obtaining and Modifying Encryption Levels
219
220Encrypting application files enhances data security by preventing files from unauthorized access. Different application files require different levels of protection.
221
222In 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).
223
224- 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.
225- EL2: For sensitive files, such as personal privacy data, the application can place them in a directory with the user-level encryption (EL2).
226- 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.
227- 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.
228- 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.
229
230You 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).
231```ts
232import { UIAbility, contextConstant, AbilityConstant, Want } from '@kit.AbilityKit';
233
234export default class EntryAbility extends UIAbility {
235  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
236    // Before storing common information, switch the encryption level to EL1.
237    this.context.area = contextConstant.AreaMode.EL1; // Change the encryption level.
238    // Store common information.
239
240    // Before storing sensitive information, switch the encryption level to EL2.
241    this.context.area = contextConstant.AreaMode.EL2; // Change the encryption level.
242    // Store sensitive information.
243
244    // Before storing sensitive information, switch the encryption level to EL3.
245    this.context.area = contextConstant.AreaMode.EL3; // Change the encryption level.
246    // Store sensitive information.
247
248    // Before storing sensitive information, switch the encryption level to EL4.
249    this.context.area = contextConstant.AreaMode.EL4; // Change the encryption level.
250    // Store sensitive information.
251
252    // Before storing sensitive information, switch the encryption level to EL5.
253    this.context.area = contextConstant.AreaMode.EL5; // Change the encryption level.
254    // Store sensitive information.
255  }
256}
257```
258```ts
259import { contextConstant, common } from '@kit.AbilityKit';
260import { promptAction } from '@kit.ArkUI';
261
262@Entry
263@Component
264struct Page_Context {
265  private context = getContext(this) as common.UIAbilityContext;
266
267  build() {
268    Column() {
269      //...
270      List({ initialIndex: 0 }) {
271        //...
272        ListItem() {
273          Row() {
274            //...
275          }
276          .onClick(() => {
277            // Before storing common information, switch the encryption level to EL1.
278            if (this.context.area === contextConstant.AreaMode.EL2) { // Obtain the area.
279              this.context.area = contextConstant.AreaMode.EL1; // Modify the area.
280              promptAction.showToast({
281                message: 'SwitchToEL1'
282              });
283            }
284            // Store common information.
285          })
286        }
287        //...
288        ListItem() {
289          Row() {
290            //...
291          }
292          .onClick(() => {
293            // Before storing sensitive information, switch the encryption level to EL2.
294            if (this.context.area === contextConstant.AreaMode.EL1) { // Obtain the area.
295              this.context.area = contextConstant.AreaMode.EL2; // Modify the area.
296              promptAction.showToast({
297                message: 'SwitchToEL2'
298              });
299            }
300            // Store sensitive information.
301          })
302        }
303        //...
304      }
305      //...
306    }
307    //...
308  }
309}
310```
311
312
313### Obtaining the Context of Other Modules in the Current Application
314
315Call [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.
316
317  ```ts
318  import { common, application } from '@kit.AbilityKit';
319  import { promptAction } from '@kit.ArkUI';
320  import { BusinessError } from '@kit.BasicServicesKit';
321
322  let storageEventCall = new LocalStorage();
323
324  @Entry(storageEventCall)
325  @Component
326  struct Page_Context {
327    private context = getContext(this) as common.UIAbilityContext;
328
329    build() {
330      Column() {
331        //...
332        List({ initialIndex: 0 }) {
333          ListItem() {
334            Row() {
335              //...
336            }
337            .onClick(() => {
338              let moduleName2: string = 'entry';
339              application.createModuleContext(this.context, moduleName2)
340                .then((data: common.Context) => {
341                  console.info(`CreateModuleContext success, data: ${JSON.stringify(data)}`);
342                  if (data !== null) {
343                    promptAction.showToast({
344                      message: ('Context obtained.')
345                    });
346                  }
347                })
348                .catch((err: BusinessError) => {
349                  console.error(`CeateMudleContext failed, err code:${err.code}, err msg: ${err.message}`);
350                });
351            })
352          }
353          //...
354        }
355        //...
356      }
357      //...
358    }
359  }
360  ```
361
362
363### Subscribing to UIAbility Lifecycle Changes in a Process
364
365In 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.
366
367[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.
368
369
370```ts
371import { AbilityConstant, AbilityLifecycleCallback, UIAbility, Want } from '@kit.AbilityKit';
372import { hilog } from '@kit.PerformanceAnalysisKit';
373import { window } from '@kit.ArkUI';
374import  { BusinessError } from '@kit.BasicServicesKit';
375
376const TAG: string = '[LifecycleAbility]';
377const DOMAIN_NUMBER: number = 0xFF00;
378
379export default class LifecycleAbility extends UIAbility {
380  // Define a lifecycle ID.
381  lifecycleId: number = -1;
382
383  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
384    // Define a lifecycle callback object.
385    let abilityLifecycleCallback: AbilityLifecycleCallback = {
386      // Called when a UIAbility is created.
387      onAbilityCreate(uiAbility) {
388        hilog.info(DOMAIN_NUMBER, TAG, `onAbilityCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
389      },
390      // Called when a window is created.
391      onWindowStageCreate(uiAbility, windowStage: window.WindowStage) {
392        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
393        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageCreate windowStage: ${JSON.stringify(windowStage)}`);
394      },
395      // Called when the window becomes active.
396      onWindowStageActive(uiAbility, windowStage: window.WindowStage) {
397        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageActive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
398        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageActive windowStage: ${JSON.stringify(windowStage)}`);
399      },
400      // Called when the window becomes inactive.
401      onWindowStageInactive(uiAbility, windowStage: window.WindowStage) {
402        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageInactive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
403        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageInactive windowStage: ${JSON.stringify(windowStage)}`);
404      },
405      // Called when the window is destroyed.
406      onWindowStageDestroy(uiAbility, windowStage: window.WindowStage) {
407        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
408        hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageDestroy windowStage: ${JSON.stringify(windowStage)}`);
409      },
410      // Called when the UIAbility is destroyed.
411      onAbilityDestroy(uiAbility) {
412        hilog.info(DOMAIN_NUMBER, TAG, `onAbilityDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
413      },
414      // Called when the UIAbility is switched from the background to the foreground.
415      onAbilityForeground(uiAbility) {
416        hilog.info(DOMAIN_NUMBER, TAG, `onAbilityForeground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
417      },
418      // Called when the UIAbility is switched from the foreground to the background.
419      onAbilityBackground(uiAbility) {
420        hilog.info(DOMAIN_NUMBER, TAG, `onAbilityBackground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
421      },
422      // Called when UIAbility is continued on another device.
423      onAbilityContinue(uiAbility) {
424        hilog.info(DOMAIN_NUMBER, TAG, `onAbilityContinue uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
425      }
426    };
427    // Obtain the application context.
428    let applicationContext = this.context.getApplicationContext();
429    try {
430      // Register the application lifecycle callback.
431      this.lifecycleId = applicationContext.on('abilityLifecycle', abilityLifecycleCallback);
432    } catch (err) {
433      let code = (err as BusinessError).code;
434      let message = (err as BusinessError).message;
435      hilog.error(DOMAIN_NUMBER, TAG, `Failed to register applicationContext. Code is ${code}, message is ${message}`);
436    }
437
438    hilog.info(DOMAIN_NUMBER, TAG, `register callback number: ${this.lifecycleId}`);
439  }
440  //...
441  onDestroy(): void {
442    // Obtain the application context.
443    let applicationContext = this.context.getApplicationContext();
444    try {
445      // Deregister the application lifecycle callback.
446      applicationContext.off('abilityLifecycle', this.lifecycleId);
447    } catch (err) {
448      let code = (err as BusinessError).code;
449      let message = (err as BusinessError).message;
450      hilog.error(DOMAIN_NUMBER, TAG, `Failed to unregister applicationContext. Code is ${code}, message is ${message}`);
451    }
452  }
453}
454```
455