一、背景
在鸿蒙开发中,应用上下文Context是一个很重要的知识点,特此整理下加深印象
二、概念
Context是应用的核心上下文对象,提供基础信息与能力。
2.1 核心理解 -
身份凭证:标识应用身份信息(包名、版本、权限等)
能力入口:提供访问系统服务和资源的统一接口
通信桥梁:连接应用内部组件与外部系统
2.2 类型体系
Context
├── ApplicationContext (应用级上下文)
├── UIAbilityContext (UIAbility上下文)
├── ExtensionContext (扩展能力上下文)
└── FormExtensionContext (卡片上下文)
2.3 持有关系
- 每个UIAbility实例持有自己的UIAbilityContext
- ApplicationContext由整个应用共享
- 组件通过getContext()获取所属Ability的上下文
不同类型Context的继承关系如下:

不同类型Context的持有关系如下:

三、为什么需要 Context
3.1、解决的核心问题
在没有Context的情况下,面临的问题
| 问题 | 解决前 | 解决后 |
|---|---|---|
| 资源访问混乱 | 每个组件自行管理资源,容易冲突 | 统一资源管理,安全隔离 |
| 组件通信困难 | 组件间直接依赖,耦合度高 | 通过Context解耦,标准化通信 |
| 权限管理分散 | 权限检查逻辑重复,安全性差 | 集中权限管理,安全可控 |
| 生命周期复杂 | 各组件自行管理状态,难以维护 | 统一生命周期管理 |
简言之,主要是为了简化数据共享和系统交互
四、Context 的主要作用
| 作用类别 | 具体功能 |
|---|---|
| 资源管理 | 获取 ResourceManager、访问应用资源 |
| 组件启动 | 启动 Ability、Service、DataAbility |
| 文件操作 | 获取应用文件目录、缓存目录 |
| 权限管理 | 权限申请和验证 |
| 系统服务 | 访问窗口管理、通知服务等 |
| 配置信息 | 获取应用包名、版本信息等 |
五、Context使用场景
场景1、资源管理能力
5.1.1、同步获取格式化字符串
解决的问题:
-
字符串格式化:处理带占位符的字符串资源(如:"欢迎%s,今天是第%d天")
-
同步执行:在需要立即获取字符串值的场景使用
-
类型安全:参数类型明确为
string | number
import { common } from "@kit.AbilityKit";
export function getStringFromResourceSync(resource: Resource, ...args: Array<string | number>): string {
const context = getContext() as common.UIAbilityContext;
return context.resourceManager.getStringSync(resource.id, ...args)
}
使用场景:
import { getStringFromResourceSync } from '../view/utils'
@Entry
@Component
struct Index {
build() {
// 资源定义:app.string.welcome_message = "欢迎%s,您是第%d位访客"
Text(getStringFromResourceSync($r('app.string.welcome_message'), '张三', 5))
// 结果: "欢迎张三,您是第5位访客"
}
}
5.1.2、同步获取普通字符串
解决的问题:
-
简单字符串访问:不需要格式化的普通字符串资源
-
零延迟获取:同步调用,立即返回值
-
错误传播:如果资源不存在会直接抛出异常
export function getStringResourceSync(resource: Resource) {
const context = getContext() as common.UIAbilityContext;
return context.resourceManager.getStringSync(resource)
}
使用场景:
import { getStringResourceSync } from '../view/utils'
import { router } from '@kit.ArkUI'
@Entry
@Component
struct Index {
build() {
Column({ space: 20 }) {
Button('点击')
.onClick(() => {
router.pushUrl({
url: 'pages/mine',
params: {
key: getStringResourceSync($r('app.string.scroll_open_accurate_search'))
}
})
})
}
}
}
说明:
此处是将
Resource对象转换为实际的string值,在需要传递字符串值的场景(路由、API、配置等)中必不可少
场景二、组件启动与管理
// 启动其他Ability
let want: Want = {
bundleName: 'com.example.app',
abilityName: 'DetailAbility',
parameters: { id: 123 }
};
await context.startAbility(want);
// 启动服务
await context.startServiceExtensionAbility(want);
场景三、权限管理
具体能力:
-
权限申请:
abilityAccessCtrl.AtManager.requestPermissionsFromUser() -
上下文获取:通过UI组件的上下文获取UIAbilityContext
-
用户交互:显示系统原生的权限申请对话框
前提:在 module.json5 中进行权限声明
动态申请权限:
import { abilityAccessCtrl, common, PermissionRequestResult, Permissions } from '@kit.AbilityKit'
import { BusinessError } from '@kit.BasicServicesKit'
@Entry
@Component
struct Index {
build() {
Column({ space: 20 }) {
Button('点击获取位置权限')
.onClick(() => {
this.goPermission()
})
}
}
goPermission() {
// 位置权限申请
const locationPermissions: Array<Permissions> = [
'ohos.permission.APPROXIMATELY_LOCATION',
'ohos.permission.LOCATION',
];
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
let context: Context = this.getUIContext().getHostContext() as common.UIAbilityContext;
atManager.requestPermissionsFromUser(context, locationPermissions,
(err: BusinessError, data: PermissionRequestResult) => {
if (err) {
console.error(`requestPermissionsFromUser fail, code: ${err.code}, message: ${err.message}`);
} else {
console.info(`requestPermissionsFromUser success, result: ${data}`);
console.info('requestPermissionsFromUser data permissions:' + data.permissions);
console.info('requestPermissionsFromUser data authResults:' + data.authResults);
console.info('requestPermissionsFromUser data dialogShownResults:' + data.dialogShownResults);
}
})
}
}
场景四、系统服务访问
在窗口设置沉浸式页面
使用Window.setWindowLayoutFullScreen()方法设置窗口为全屏模式。
import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage) {
// 1.Get the main window of the application.
let windowClass: window.Window | undefined = undefined;
windowStage.getMainWindow().then(windowClass => {
console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(windowClass));
// 2.Set the window to full screen to achieve immersive effects.
windowClass.setWindowLayoutFullScreen(true).then(() => {
console.info('Succeeded in setting the window layout to full-screen mode.');
}).catch((e: BusinessError) => {
console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(e));
})
}).catch((err: BusinessError) => {
console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(err));
})
// 3.Load the corresponding target page for the immersive window.
windowStage.loadContent("pages/Index", (err) => {
if (err.code) {
console.error('Failed to load the content. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in loading the content.');
});
}
};
场景五、事件通信
@Entry
@Component
struct Index {
aboutToDisappear(): void {
//组件销毁时取消事件订阅
getContext().eventHub.off('dataUpdate')
}
build() {
Column({ space: 20 }) {
Button('点击')
.onClick(() => {
//发送事件
getContext().eventHub.emit('dataUpdate', (data: string) => {
console.log('收到数据更新:', data);
});
})
}
}
}
六、Context 解决的问题
6.1、架构层面
通过Context实现组件间安全通信
统一资源调度,避免冲突
标准化组件生命周期
6.2、开发效率与安全上
通用能力封装,减少重复代码
安全数据共享机制
组件访问权限验证
1616

被折叠的 条评论
为什么被折叠?



