應(yīng)用上下文Context
概述
[Context]是應(yīng)用中對(duì)象的上下文,其提供了應(yīng)用的一些基礎(chǔ)信息,例如resourceManager(資源管理)、applicationInfo(當(dāng)前應(yīng)用信息)、dir(應(yīng)用文件路徑)、area(文件分區(qū))等,以及應(yīng)用的一些基本方法,例如createBundleContext()、getApplicationContext()等。UIAbility組件和各種ExtensionAbility派生類組件都有各自不同的Context類。分別有基類Context、ApplicationContext、AbilityStageContext、UIAbilityContext、ExtensionContext、ServiceExtensionContext等Context。
- 各類Context的繼承關(guān)系
![context-inheritance] - 各類Context的持有關(guān)系
![context-holding] - 各類Context的獲取方式
獲取[UIAbilityContext]。每個(gè)UIAbility中都包含了一個(gè)Context屬性,提供操作應(yīng)用組件、獲取應(yīng)用組件的配置信息等能力。
import UIAbility from '@ohos.app.ability.UIAbility'; import type AbilityConstant from '@ohos.app.ability.AbilityConstant'; import type Want from '@ohos.app.ability.Want'; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { let uiAbilityContext = this.context; //... } }
說(shuō)明:
開發(fā)前請(qǐng)熟悉鴻蒙開發(fā)指導(dǎo)文檔 :[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
]
頁(yè)面中獲取UIAbility實(shí)例的上下文信息請(qǐng)參見[獲取UIAbility的上下文信息]。獲取特定場(chǎng)景[ExtensionContext]。以ServiceExtensionContext為例,表示后臺(tái)服務(wù)的上下文環(huán)境,繼承自ExtensionContext,提供后臺(tái)服務(wù)相關(guān)的接口能力。
import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility'; import type Want from '@ohos.app.ability.Want'; export default class ServiceExtAbility extends ServiceExtensionAbility { onCreate(want: Want) { let serviceExtensionContext = this.context; //... } }
獲取[AbilityStageContext]。Module級(jí)別的Context,和基類Context相比,額外提供HapModuleInfo、Configuration等信息。
import AbilityStage from '@ohos.app.ability.AbilityStage'; export default class MyAbilityStage extends AbilityStage { onCreate(): void { let abilityStageContext = this.context; //... } }
獲取[ApplicationContext]。應(yīng)用級(jí)別的Context。ApplicationContext在基類Context的基礎(chǔ)上提供了訂閱應(yīng)用內(nèi)應(yīng)用組件的生命周期的變化、訂閱系統(tǒng)內(nèi)存變化和訂閱應(yīng)用內(nèi)系統(tǒng)環(huán)境的變化的能力,在UIAbility、ExtensionAbility、AbilityStage中均可以獲取。
import UIAbility from '@ohos.app.ability.UIAbility'; import type AbilityConstant from '@ohos.app.ability.AbilityConstant'; import type Want from '@ohos.app.ability.Want'; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { let applicationContext = this.context.getApplicationContext(); //... } }
Context的典型使用場(chǎng)景
本章節(jié)通過(guò)如下典型場(chǎng)景來(lái)介紹Context的用法:
- [獲取應(yīng)用文件路徑]
- [獲取和修改加密分區(qū)]
- [獲取本應(yīng)用中其他module的context]
- [訂閱進(jìn)程內(nèi)UIAbility生命周期變化]
獲取應(yīng)用文件路徑
[基類Context]提供了獲取應(yīng)用文件路徑的能力,ApplicationContext、AbilityStageContext、UIAbilityContext和ExtensionContext均繼承該能力。應(yīng)用文件路徑屬于應(yīng)用沙箱路徑,具體請(qǐng)參見[應(yīng)用沙箱目錄](méi)。
上述各類Context獲取的應(yīng)用文件路徑有所不同。
通過(guò)ApplicationContext獲取應(yīng)用級(jí)別的應(yīng)用文件路徑,此路徑是應(yīng)用全局信息推薦的存放路徑,這些文件會(huì)跟隨應(yīng)用的卸載而刪除。
屬性 路徑 bundleCodeDir <路徑前綴>/el1/bundle cacheDir <路徑前綴>/<加密等級(jí)>/base/cache filesDir <路徑前綴>/<加密等級(jí)>/base/files preferencesDir <路徑前綴>/<加密等級(jí)>/base/preferences tempDir <路徑前綴>/<加密等級(jí)>/base/temp databaseDir <路徑前綴>/<加密等級(jí)>/database distributedFilesDir <路徑前綴>/el2/distributedFiles cloudFileDir12+ <路徑前綴>/el2/hmdfs/cloud/data 示例代碼如下所示。
import common from '@ohos.app.ability.common'; import hilog from '@ohos.hilog'; import promptAction from '@ohos.promptAction'; const TAG: string = '[Page_Context]'; const DOMAIN_NUMBER: number = 0xFF00; @Entry @Component struct Page_Context { private context = getContext(this) as common.UIAbilityContext; build() { Column() { //... List({ initialIndex: 0 }) { ListItem() { Row() { //... } .onClick(() = > { let applicationContext = this.context.getApplicationContext(); let cacheDir = applicationContext.cacheDir; let tempDir = applicationContext.tempDir; let filesDir = applicationContext.filesDir; let databaseDir = applicationContext.databaseDir; let bundleCodeDir = applicationContext.bundleCodeDir; let distributedFilesDir = applicationContext.distributedFilesDir; let preferencesDir = applicationContext.preferencesDir; // 獲取應(yīng)用文件路徑 let filePath = tempDir + 'test.txt'; hilog.info(DOMAIN_NUMBER, TAG, `filePath: ${filePath}`); if (filePath !== null) { promptAction.showToast({ message: filePath }); } }) } //... } //... } //... } }
通過(guò)AbilityStageContext、UIAbilityContext、ExtensionContext獲取HAP級(jí)別的應(yīng)用文件路徑。此路徑是HAP相關(guān)信息推薦的存放路徑,這些文件會(huì)跟隨HAP的卸載而刪除,但不會(huì)影響應(yīng)用級(jí)別路徑的文件,除非該應(yīng)用的HAP已全部卸載。
屬性 路徑 bundleCodeDir <路徑前綴>/el1/bundle cacheDir <路徑前綴>/<加密等級(jí)>/base/haps//cache filesDir <路徑前綴>/<加密等級(jí)>/base/haps//files preferencesDir <路徑前綴>/<加密等級(jí)>/base/haps//preferences tempDir <路徑前綴>/<加密等級(jí)>/base/haps//temp databaseDir <路徑前綴>/<加密等級(jí)>/database/ **** distributedFilesDir <路徑前綴>/el2/distributedFiles/ **** cloudFileDir12+ <路徑前綴>/el2/hmdfs/cloud/data/ **** 示例代碼如下所示。
import common from '@ohos.app.ability.common'; import hilog from '@ohos.hilog'; import promptAction from '@ohos.promptAction'; const TAG: string = '[Page_Context]'; const DOMAIN_NUMBER: number = 0xFF00; @Entry @Component struct Page_Context { private context = getContext(this) as common.UIAbilityContext; build() { Column() { //... List({ initialIndex: 0 }) { ListItem() { Row() { //... } .onClick(() = > { let cacheDir = this.context.cacheDir; let tempDir = this.context.tempDir; let filesDir = this.context.filesDir; let databaseDir = this.context.databaseDir; let bundleCodeDir = this.context.bundleCodeDir; let distributedFilesDir = this.context.distributedFilesDir; let preferencesDir = this.context.preferencesDir; // 獲取應(yīng)用文件路徑 let filePath = tempDir + 'test.txt'; hilog.info(DOMAIN_NUMBER, TAG, `filePath: ${filePath}`); if (filePath !== null) { promptAction.showToast({ message: filePath }); } }) } //... } //... } //... } }
獲取和修改加密分區(qū)
應(yīng)用文件加密是一種保護(hù)數(shù)據(jù)安全的方法,可以使得文件在未經(jīng)授權(quán)訪問(wèn)的情況下得到保護(hù)。在不同的場(chǎng)景下,應(yīng)用需要不同程度的文件保護(hù)。
在實(shí)際應(yīng)用中,開發(fā)者需要根據(jù)不同場(chǎng)景的需求選擇合適的加密分區(qū),從而保護(hù)應(yīng)用數(shù)據(jù)的安全。通過(guò)合理使用不同級(jí)別的加密分區(qū),可以有效提高應(yīng)用數(shù)據(jù)的安全性。關(guān)于不同分區(qū)的權(quán)限說(shuō)明,詳見[ContextConstant]的AreaMode。
- EL1:對(duì)于私有文件,如鬧鈴、壁紙等,應(yīng)用可以將這些文件放到設(shè)備級(jí)加密分區(qū)(EL1)中,以保證在用戶輸入密碼前就可以被訪問(wèn)。
- EL2:對(duì)于更敏感的文件,如個(gè)人隱私信息等,應(yīng)用可以將這些文件放到更高級(jí)別的加密分區(qū)(EL2)中,以保證更高的安全性。
- EL3:對(duì)于應(yīng)用中的記錄步數(shù)、文件下載、音樂(lè)播放,需要在鎖屏?xí)r讀寫和創(chuàng)建新文件,放在(EL3)的加密分區(qū)比較合適。
- EL4:對(duì)于用戶安全信息相關(guān)的文件,鎖屏?xí)r不需要讀寫文件、也不能創(chuàng)建文件,放在(EL4)的加密分區(qū)更合適。
要實(shí)現(xiàn)獲取和設(shè)置當(dāng)前加密分區(qū),可以通過(guò)讀寫[Context]的area
屬性來(lái)實(shí)現(xiàn)。
import UIAbility from '@ohos.app.ability.UIAbility';
import contextConstant from '@ohos.app.ability.contextConstant';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import Want from '@ohos.app.ability.Want';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
// 存儲(chǔ)普通信息前,切換到EL1設(shè)備級(jí)加密
this.context.area = contextConstant.AreaMode.EL1; // 切換area
// 存儲(chǔ)普通信息
// 存儲(chǔ)敏感信息前,切換到EL2用戶級(jí)加密
this.context.area = contextConstant.AreaMode.EL2; // 切換area
// 存儲(chǔ)敏感信息
// 存儲(chǔ)敏感信息前,切換到EL3用戶級(jí)加密
this.context.area = contextConstant.AreaMode.EL3; // 切換area
// 存儲(chǔ)敏感信息
// 存儲(chǔ)敏感信息前,切換到EL4用戶級(jí)加密
this.context.area = contextConstant.AreaMode.EL4; // 切換area
// 存儲(chǔ)敏感信息
}
}
import contextConstant from '@ohos.app.ability.contextConstant';
import common from '@ohos.app.ability.common';
import promptAction from '@ohos.promptAction';
@Entry
@Component
struct Page_Context {
private context = getContext(this) as common.UIAbilityContext;
build() {
Column() {
//...
List({ initialIndex: 0 }) {
//...
ListItem() {
Row() {
//...
}
.onClick(() = > {
// 存儲(chǔ)普通信息前,切換到EL1設(shè)備級(jí)加密
if (this.context.area === contextConstant.AreaMode.EL2) { // 獲取area
this.context.area = contextConstant.AreaMode.EL1; // 修改area
promptAction.showToast({
message: $r('app.string.SwitchToEL1')
});
}
// 存儲(chǔ)普通信息
})
}
//...
ListItem() {
Row() {
//...
}
.onClick(() = > {
// 存儲(chǔ)敏感信息前,切換到EL2用戶級(jí)加密
if (this.context.area === contextConstant.AreaMode.EL1) { // 獲取area
this.context.area = contextConstant.AreaMode.EL2; // 修改area
promptAction.showToast({
message: $r('app.string.SwitchToEL2')
});
}
// 存儲(chǔ)敏感信息
})
}
//...
}
//...
}
//...
}
}
獲取本應(yīng)用中其他Module的Context
調(diào)用createModuleContext(moduleName:string)
方法,獲取本應(yīng)用中其他Module的Context。獲取到其他Module的Context之后,即可獲取到相應(yīng)Module的資源信息。
import promptAction from '@ohos.promptAction';
import common from '@ohos.app.ability.common';
let storageEventCall = new LocalStorage();
@Entry(storageEventCall)
@Component
struct Page_Context {
private context = getContext(this) as common.UIAbilityContext;
build() {
Column() {
//...
List({ initialIndex: 0 }) {
ListItem() {
Row() {
//...
}
.onClick(() = > {
let moduleName2: string = 'entry';
let moduleContext: Context = this.context.createModuleContext(moduleName2);
if (moduleContext !== null) {
promptAction.showToast({
message: ('成功獲取Context')
});
}
})
}
//...
}
//...
}
//...
}
}
訂閱進(jìn)程內(nèi)UIAbility生命周期變化
在應(yīng)用內(nèi)的DFX統(tǒng)計(jì)場(chǎng)景中,如需要統(tǒng)計(jì)對(duì)應(yīng)頁(yè)面停留時(shí)間和訪問(wèn)頻率等信息,可以使用訂閱進(jìn)程內(nèi)UIAbility生命周期變化功能。
通過(guò)[ApplicationContext]提供的能力,可以訂閱進(jìn)程內(nèi)UIAbility生命周期變化。當(dāng)進(jìn)程內(nèi)的UIAbility生命周期變化時(shí),如創(chuàng)建、可見/不可見、獲焦/失焦、銷毀等,會(huì)觸發(fā)相應(yīng)的回調(diào)函數(shù)。每次注冊(cè)回調(diào)函數(shù)時(shí),都會(huì)返回一個(gè)監(jiān)聽生命周期的ID,此ID會(huì)自增+1。當(dāng)超過(guò)監(jiān)聽上限數(shù)量2^63-1時(shí),會(huì)返回-1。以[UIAbilityContext]中的使用為例進(jìn)行說(shuō)明。
`HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿`
import type AbilityConstant from '@ohos.app.ability.AbilityConstant';
import type AbilityLifecycleCallback from '@ohos.app.ability.AbilityLifecycleCallback';
import hilog from '@ohos.hilog';
import UIAbility from '@ohos.app.ability.UIAbility';
import type Want from '@ohos.app.ability.Want';
import type window from '@ohos.window';
const TAG: string = '[LifecycleAbility]';
const DOMAIN_NUMBER: number = 0xFF00;
export default class LifecycleAbility extends UIAbility {
// 定義生命周期ID
lifecycleId: number = -1;
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
// 定義生命周期回調(diào)對(duì)象
let abilityLifecycleCallback: AbilityLifecycleCallback = {
// 當(dāng)UIAbility創(chuàng)建時(shí)被調(diào)用
onAbilityCreate(uiAbility) {
hilog.info(DOMAIN_NUMBER, TAG, `onAbilityCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
},
// 當(dāng)窗口創(chuàng)建時(shí)被調(diào)用
onWindowStageCreate(uiAbility, windowStage: window.WindowStage) {
hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageCreate windowStage: ${JSON.stringify(windowStage)}`);
},
// 當(dāng)窗口處于活動(dòng)狀態(tài)時(shí)被調(diào)用
onWindowStageActive(uiAbility, windowStage: window.WindowStage) {
hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageActive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageActive windowStage: ${JSON.stringify(windowStage)}`);
},
// 當(dāng)窗口處于非活動(dòng)狀態(tài)時(shí)被調(diào)用
onWindowStageInactive(uiAbility, windowStage: window.WindowStage) {
hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageInactive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageInactive windowStage: ${JSON.stringify(windowStage)}`);
},
// 當(dāng)窗口被銷毀時(shí)被調(diào)用
onWindowStageDestroy(uiAbility, windowStage: window.WindowStage) {
hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
hilog.info(DOMAIN_NUMBER, TAG, `onWindowStageDestroy windowStage: ${JSON.stringify(windowStage)}`);
},
// 當(dāng)UIAbility被銷毀時(shí)被調(diào)用
onAbilityDestroy(uiAbility) {
hilog.info(DOMAIN_NUMBER, TAG, `onAbilityDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
},
// 當(dāng)UIAbility從后臺(tái)轉(zhuǎn)到前臺(tái)時(shí)觸發(fā)回調(diào)
onAbilityForeground(uiAbility) {
hilog.info(DOMAIN_NUMBER, TAG, `onAbilityForeground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
},
// 當(dāng)UIAbility從前臺(tái)轉(zhuǎn)到后臺(tái)時(shí)觸發(fā)回調(diào)
onAbilityBackground(uiAbility) {
hilog.info(DOMAIN_NUMBER, TAG, `onAbilityBackground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
},
// 當(dāng)UIAbility遷移時(shí)被調(diào)用
onAbilityContinue(uiAbility) {
hilog.info(DOMAIN_NUMBER, TAG, `onAbilityContinue uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
}
};
// 獲取應(yīng)用上下文
let applicationContext = this.context.getApplicationContext();
// 注冊(cè)應(yīng)用內(nèi)生命周期回調(diào)
this.lifecycleId = applicationContext.on('abilityLifecycle', abilityLifecycleCallback);
hilog.info(DOMAIN_NUMBER, TAG, `register callback number: ${this.lifecycleId}`);
}
//...
onDestroy() : void {
// 獲取應(yīng)用上下文
let applicationContext = this.context.getApplicationContext();
// 取消應(yīng)用內(nèi)生命周期回調(diào)
applicationContext.off('abilityLifecycle', this.lifecycleId);
}
};
審核編輯 黃宇
-
框架
+關(guān)注
關(guān)注
0文章
398瀏覽量
17404 -
鴻蒙
+關(guān)注
關(guān)注
57文章
2302瀏覽量
42689
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論