应用上下文 Context:我理解的几种「视角」
可以把 Context 理解成: 「系统给你的一张工作证 + 能力集合,不同层级的证能做的事不一样。」
1. Context 总体概念
-
Context = 当前对象的运行环境 + 能力入口
-
提供信息:
resourceManager(资源)applicationInfo(应用信息)area(文件加密分区)- 各种路径(cacheDir、filesDir 等)
- 各类监听与能力(前后台、生命周期、清理数据、设置语言等)
2. 常见几类 Context 对比
记忆口诀:App(全局) → Module → Ability → Extension → UI(窗口)
| 类型 | 作用层级 | 主要能力 | 获取方式 | 典型场景 |
|---|---|---|---|---|
ApplicationContext | 应用级(整个 APP) | 应用基本信息、应用级路径、环境/前后台/生命周期监听、加密分区、清理数据等 | this.context.getApplicationContext() | 需要全局视角:监听整个应用前后台、UIAbility 生命周期、设置应用语言/主题等 |
AbilityStageContext | Module 级 | HapModuleInfo、Configuration、模块级路径 | 在 AbilityStage 中直接 this.context | 在 AbilityStage 里做模块初始化、获取模块路径 |
UIAbilityContext | 单个 UIAbility | abilityInfo、currentHapModuleInfo、startAbility/terminateSelf、连接服务等 | 在 UIAbility 中 this.context;在页面中 this.getUIContext().getHostContext() | 第三方应用最常用:页面里启动其他 Ability、结束当前 Ability、拿 BundleName 等 |
ExtensionContext | 单个 ExtensionAbility | 每种 Extension 有专属能力,例如 FormExtensionContext 支持卡片 API | 在 ExtensionAbility 中 this.context | 卡片、输入法、AppServiceExtension 等组件内部用 |
UIContext | ArkUI UI 实例级 | UI 相关能力:弹 Toast、Alert、软键盘避让模式、获取字体等 | 组件内 this.getUIContext();Window 上 window.getUIContext() | 纯 UI 操作,不管 Bundle/Ability,只管「这个 UI 实例」 |
⚠ 重要注意:
不同 Context 能力不同,不能强行互转。 比如
ApplicationContext有setFontSizeScale(),UIAbilityContext没有, 即使你「强转」也没用,方法本身就不存在。
3. 各类 Context 的获取方式速记
3.1 ApplicationContext(全局)
在 UIAbility 里:
import { UIAbility, AbilityConstant, Want } from '@kit.AbilityKit';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
const applicationContext = this.context.getApplicationContext();
// 在这里可以注册前后台监听、生命周期监听、获取应用信息等
}
}
在 AbilityStage / ExtensionAbility 中也类似:this.context.getApplicationContext()。
3.2 AbilityStageContext(模块级)
import { AbilityStage } from '@kit.AbilityKit';
export default class MyAbilityStage extends AbilityStage {
onCreate(): void {
const abilityStageContext = this.context;
// 拿模块信息、模块级路径等
}
}
3.3 获取其他 Module 的 Context(同一应用)
import { common, application } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct Page_Context {
private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
build() {
// ...
ListItem() {
Row() { /* ... */ }
.onClick(() => {
const moduleName2 = 'entry';
application.createModuleContext(this.context, moduleName2)
.then((data: common.Context) => {
console.info(`CreateModuleContext success, data: ${JSON.stringify(data)}`);
if (data) {
this.getUIContext().getPromptAction().showToast({ message: '成功获取Context' });
}
})
.catch((err: BusinessError) => {
console.error(`CreateModuleContext failed, err code:${err.code}, err msg: ${err.message}`);
});
})
}
}
}
3.4 UIAbilityContext
在 UIAbility 类里:
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
const context = this.context; // UIAbilityContext
}
}
在页面里:
写法 1:先定义成员变量:
import { common, Want } from '@kit.AbilityKit';
@Entry
@Component
struct Page_EventHub {
private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
startAbilityTest(): void {
const want: Want = { /* ... */ };
this.context.startAbility(want);
}
}
写法 2:临时获取:
@Entry
@Component
struct Page_UIAbilityComponentsBasicUsage {
startAbilityTest(): void {
const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
const want: Want = { /* ... */ };
context.startAbility(want);
}
}
结束当前 UIAbility:
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct Page_UIAbilityComponentsBasicUsage {
build() {
Column() {
Button('FuncAbilityB')
.onClick(() => {
const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
try {
context.terminateSelf((err: BusinessError) => {
if (err.code) {
console.error(`terminateSelf failed, code is ${err.code}, message is ${err.message}.`);
return;
}
console.info(`terminateSelf succeed.`);
});
} catch (err) {
const code = (err as BusinessError).code;
const message = (err as BusinessError).message;
console.error(`terminateSelf failed, code is ${code}, message is ${message}.`);
}
})
}
}
}
3.5 ExtensionContext(以 FormExtension 为例)
import { FormExtensionAbility, formBindingData } from '@kit.FormKit';
import { Want } from '@kit.AbilityKit';
export default class MyFormExtensionAbility extends FormExtensionAbility {
onAddForm(want: Want) {
const formExtensionContext = this.context;
// ... 使用卡片上下文能力
const dataObj: Record<string, string> = {
temperature: '11c',
time: '11:00'
};
return formBindingData.createFormBindingData(dataObj);
}
}
4. 文件路径与应用沙箱:不同 Context 得到的路径有啥区别?
记忆点:
- ApplicationContext → 应用级目录(不带模块名)
- AbilityStageContext / UIAbilityContext / ExtensionContext → 模块级目录(路径里带
<module-name>)
典型属性(简化版):
| 属性 | ApplicationContext 的路径 | AbilityStage / UIAbility / Extension 的路径 |
|---|---|---|
bundleCodeDir | <前缀>/el1/bundle | <前缀>/el1/bundle(一样) |
cacheDir | <前缀>/<加密等级>/base/cache | <前缀>/<加密等级>/base/haps/<module-name>/cache |
filesDir | <前缀>/<加密等级>/base/files | <前缀>/<加密等级>/base/haps/<module-name>/files |
preferencesDir | <前缀>/<加密等级>/base/preferences | <前缀>/<加密等级>/base/haps/<module-name>/preferences |
tempDir | <前缀>/<加密等级>/base/temp | <前缀>/<加密等级>/base/haps/<module-name>/temp |
databaseDir | <前缀>/<加密等级>/database | <前缀>/<加密等级>/database/<module-name> |
📌 共同点:都是在应用沙箱目录里,卸载应用时会被清理(应用级/模块级略有差别)。
4.1 获取缓存目录 cacheDir(示例)
import { common } from '@kit.AbilityKit';
const TAG: string = '[Page_Context]';
const DOMAIN_NUMBER: number = 0xFF00;
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
build() {
Button('create file')
.onClick(() => {
const applicationContext = this.context.getApplicationContext();
const cacheDir = applicationContext.cacheDir;
// 在 cacheDir 下面存放缓存文件
});
}
}
4.2 获取 filesDir 并读写文件(示例)
import { common } from '@kit.AbilityKit';
import { buffer } from '@kit.ArkTS';
import { fileIo, ReadOptions } from '@kit.CoreFileKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
const TAG: string = '[Page_Context]';
const DOMAIN_NUMBER: number = 0xFF00;
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
build() {
Button('create file')
.onClick(() => {
const applicationContext = this.context.getApplicationContext();
const filesDir = applicationContext.filesDir;
hilog.info(DOMAIN_NUMBER, TAG, `filePath: ${filesDir}`);
const file = fileIo.openSync(
filesDir + '/test.txt',
fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE
);
const writeLen = fileIo.writeSync(file.fd, 'Try to write str.');
const arrayBuffer = new ArrayBuffer(1024);
const readOptions: ReadOptions = { offset: 0, length: arrayBuffer.byteLength };
const readLen = fileIo.readSync(file.fd, arrayBuffer, readOptions);
const buf = buffer.from(arrayBuffer, 0, readLen);
hilog.info(DOMAIN_NUMBER, TAG, `the content of file: ${buf.toString()}`);
fileIo.closeSync(file);
});
}
}
5. 加密分区 area:EL1 ~ EL5 怎么理解?
Context 上有一个关键属性:area,控制当前读写使用哪个加密分区。
大致理解:
- EL1:设备级加密,锁屏前后都能访问。适合私有但不敏感数据(闹铃、壁纸等)。
- EL2:用户级更敏感数据。
- EL3:锁屏时仍需读写、创建文件的场景(步数、下载、音乐播放等)。
- EL4:安全信息,锁屏后不读写、不创建。
- EL5:更高隐私,锁屏后默认不可读写,如需锁屏后继续访问要额外申请。
切换分区的例子:
// EntryAbility.ets
import { UIAbility, contextConstant, AbilityConstant, Want } from '@kit.AbilityKit';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
// 存普通信息 → 切到 EL1
this.context.area = contextConstant.AreaMode.EL1;
// 存更敏感信息 → EL2
this.context.area = contextConstant.AreaMode.EL2;
// 需要锁屏也读写 → EL3
this.context.area = contextConstant.AreaMode.EL3;
// 安全信息锁屏不读写 → EL4
this.context.area = contextConstant.AreaMode.EL4;
// 高敏隐私 → EL5
this.context.area = contextConstant.AreaMode.EL5;
}
}
在页面里动态切换并提示:
import { contextConstant, common } from '@kit.AbilityKit';
@Entry
@Component
struct Page_Context {
private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
build() {
// 切到 EL1
ListItem()
.onClick(() => {
if (this.context.area === contextConstant.AreaMode.EL2) {
this.context.area = contextConstant.AreaMode.EL1;
this.getUIContext().getPromptAction().showToast({ message: 'SwitchToEL1' });
}
});
// 切到 EL2
ListItem()
.onClick(() => {
if (this.context.area === contextConstant.AreaMode.EL1) {
this.context.area = contextConstant.AreaMode.EL2;
this.getUIContext().getPromptAction().showToast({ message: 'SwitchToEL2' });
}
});
}
}
6. 基于 ApplicationContext 的全局监听
6.1 监听应用前后台切换
import { UIAbility, ApplicationStateChangeCallback } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
export default class LifecycleAbility extends UIAbility {
onCreate() {
const applicationStateChangeCallback: ApplicationStateChangeCallback = {
onApplicationForeground() {
console.info('applicationStateChangeCallback onApplicationForeground');
},
onApplicationBackground() {
console.info('applicationStateChangeCallback onApplicationBackground');
}
};
const applicationContext = this.context.getApplicationContext();
try {
applicationContext.on('applicationStateChange', applicationStateChangeCallback);
} catch (paramError) {
console.error(
`error: ${(paramError as BusinessError).code}, ${(paramError as BusinessError).message}`
);
}
}
}
6.2 监听 UIAbility 生命周期变化
import {
AbilityConstant,
AbilityLifecycleCallback,
UIAbility,
Want
} from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
const TAG: string = '[LifecycleAbility]';
const DOMAIN_NUMBER: number = 0xFF00;
export default class LifecycleAbility extends UIAbility {
lifecycleId: number = -1;
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
const abilityLifecycleCallback: AbilityLifecycleCallback = {
onAbilityCreate(uiAbility) {
hilog.info(DOMAIN_NUMBER, TAG, `onAbilityCreate: ${JSON.stringify(uiAbility.launchWant)}`);
},
onWindowStageCreate(uiAbility, windowStage: window.WindowStage) {
hilog.info(DOMAIN_NUMBER, TAG, 'onWindowStageCreate');
},
onWindowStageActive(uiAbility, windowStage: window.WindowStage) {
hilog.info(DOMAIN_NUMBER, TAG, 'onWindowStageActive');
},
onWindowStageInactive(uiAbility, windowStage: window.WindowStage) {
hilog.info(DOMAIN_NUMBER, TAG, 'onWindowStageInactive');
},
onWindowStageDestroy(uiAbility, windowStage: window.WindowStage) {
hilog.info(DOMAIN_NUMBER, TAG, 'onWindowStageDestroy');
},
onAbilityDestroy(uiAbility) {
hilog.info(DOMAIN_NUMBER, TAG, 'onAbilityDestroy');
},
onAbilityForeground(uiAbility) {
hilog.info(DOMAIN_NUMBER, TAG, 'onAbilityForeground');
},
onAbilityBackground(uiAbility) {
hilog.info(DOMAIN_NUMBER, TAG, 'onAbilityBackground');
},
onAbilityContinue(uiAbility) {
hilog.info(DOMAIN_NUMBER, TAG, 'onAbilityContinue');
}
};
const applicationContext = this.context.getApplicationContext();
try {
this.lifecycleId = applicationContext.on('abilityLifecycle', abilityLifecycleCallback);
} catch (err) {
const code = (err as BusinessError).code;
const message = (err as BusinessError).message;
hilog.error(DOMAIN_NUMBER, TAG, `register failed, code=${code}, msg=${message}`);
}
hilog.info(DOMAIN_NUMBER, TAG, `register callback number: ${this.lifecycleId}`);
}
onDestroy(): void {
const applicationContext = this.context.getApplicationContext();
try {
applicationContext.off('abilityLifecycle', this.lifecycleId);
} catch (err) {
const code = (err as BusinessError).code;
const message = (err as BusinessError).message;
hilog.error(DOMAIN_NUMBER, TAG, `unregister failed, code=${code}, msg=${message}`);
}
}
}
7. 一口气记住的「考试版总结」
Context 是什么?
- 是对象的运行上下文,提供资源管理、应用信息、沙箱路径、加密分区和各种系统能力的入口。
有哪几种?
ApplicationContext:应用级,全局监听/应用路径/语言主题设置/清理数据。AbilityStageContext:模块级,Module 信息 + 模块级路径。UIAbilityContext:单个 UIAbility 的上下文,负责启动/结束 Ability,拿 BundleName 等。ExtensionContext:各类 ExtensionAbility 的上下文,有各自专属能力。UIContext:ArkUI UI 实例的上下文,做弹框、软键盘避让等纯 UI 操作。
路径差异?
- ApplicationContext → 应用级
<...>/base/files- 其他 Context → 带 Module 名
<...>/base/haps/<module-name>/files
关键场景?
- ApplicationContext:监听应用前后台/能力生命周期、设置语言/主题、获取加密分区。
- UIAbilityContext:页面里
startAbility()、terminateSelf()、拿bundleName/abilityName。- AbilityStageContext:Module 初始化、环境监听、onAcceptWant(specified 模式)。
- ExtensionContext:卡片/输入法/后台服务等内部使用。