当前位置: 首页 > news >正文

HarmonyOS4.0系统性深入开发14AbilityStage组件容器

AbilityStage组件容器

AbilityStage是一个Module级别的组件容器,应用的HAP在首次加载时会创建一个AbilityStage实例,可以对该Module进行初始化等操作。

AbilityStage与Module一一对应,即一个Module拥有一个AbilityStage。

DevEco Studio默认工程中未自动生成AbilityStage,如需要使用AbilityStage的能力,可以手动新建一个AbilityStage文件,具体步骤如下。

  1. 在工程Module对应的ets目录下,右键选择“New > Directory”,新建一个目录并命名为myabilitystage。

  2. 在myabilitystage目录,右键选择“New > TypeScript File”,新建一个TypeScript文件并命名为MyAbilityStage.ts。

  3. 打开MyAbilityStage.ts文件,导入AbilityStage的依赖包,自定义类继承AbilityStage并加上需要的生命周期回调,示例中增加了一个onCreate()生命周期回调。

    import AbilityStage from '@ohos.app.ability.AbilityStage';export default class MyAbilityStage extends AbilityStage {onCreate() {// 应用的HAP在首次加载的时,为该Module初始化操作}onAcceptWant(want) {// 仅specified模式下触发return "MyAbilityStage";}
    }
    
  4. 在module.json5配置文件中,通过配置srcEntry参数来指定模块对应的代码路径,以作为HAP加载的入口。

    {"module": {"name": "entry","type": "entry","srcEntry": "./ets/myabilitystage/MyAbilityStage.ts",...}
    }
    

AbilityStage拥有onCreate()生命周期回调和onAcceptWant()、onConfigurationUpdated()、onMemoryLevel()事件回调。

  • onCreate()生命周期回调:在开始加载对应Module的第一个UIAbility实例之前会先创建AbilityStage,并在AbilityStage创建完成之后执行其onCreate()生命周期回调。AbilityStage模块提供在Module加载的时候,通知开发者,可以在此进行该Module的初始化(如资源预加载,线程创建等)能力。
  • onAcceptWant()事件回调:UIAbility指定实例模式(specified)启动时候触发的事件回调,具体使用请参见UIAbility启动模式综述。
  • onConfigurationUpdated()事件回调:当系统全局配置发生变更时触发的事件,系统语言、深浅色等,配置项目前均定义在Configuration类中。
  • onMemoryLevel()事件回调:当系统调整内存时触发的事件。

应用被切换到后台时,系统会将在后台的应用保留在缓存中。即使应用处于缓存中,也会影响系统整体性能。当系统资源不足时,系统会通过多种方式从应用中回收内存,必要时会完全停止应用,从而释放内存用于执行关键任务。为了进一步保持系统内存的平衡,避免系统停止用户的应用进程,可以在AbilityStage中的onMemoryLevel()生命周期回调中订阅系统内存的变化情况,释放不必要的资源。

import AbilityStage from '@ohos.app.ability.AbilityStage';export default class MyAbilityStage extends AbilityStage {onMemoryLevel(level) {// 根据系统可用内存的变化情况,释放不必要的内存}
}

应用上下文Context

概述

Context是应用中对象的上下文,其提供了应用的一些基础信息,例如resourceManager(资源管理)、applicationInfo(当前应用信息)、dir(应用开发路径)、area(文件分区)等,以及应用的一些基本方法,例如createBundleContext()、getApplicationContext()等。UIAbility组件和各种ExtensionAbility派生类组件都有各自不同的Context类。分别有基类Context、ApplicationContext、AbilityStageContext、UIAbilityContext、ExtensionContext、ServiceExtensionContext等Context。

  • 各类Context的继承关系

    img

  • 各类Context的持有关系

    img

  • 各类Context的获取方式

    • 获取UIAbilityContext。每个UIAbility中都包含了一个Context属性,提供操作Ability、获取Ability的配置信息、应用向用户申请授权等能力。

      import UIAbility from '@ohos.app.ability.UIAbility';
      export default class EntryAbility extends UIAbility {onCreate(want, launchParam) {let uiAbilityContext = this.context;// ...}
      }
      
    • 获取AbilityStageContext。Module级别的Context,和基类Context相比,额外提供HapModuleInfo、Configuration等信息。

      import AbilityStage from "@ohos.app.ability.AbilityStage";
      export default class MyAbilityStage extends AbilityStage {onCreate() {let abilityStageContext = this.context;// ...}
      }
      
    • 获取ApplicationContext。应用级别的Context。ApplicationContext在基类Context的基础上提供了订阅应用内Ability的生命周期的变化、订阅系统内存变化和订阅应用内系统环境的变化的能力,在UIAbility、ExtensionAbility、AbilityStage中均可以获取。

      import UIAbility from '@ohos.app.ability.UIAbility';
      export default class EntryAbility extends UIAbility {onCreate(want, launchParam) {let applicationContext = this.context.getApplicationContext();// ...}
      }
      

Context的典型使用场景

本章节通过如下典型场景来介绍Context的用法:

  • 获取应用文件路径
  • 获取和修改加密分区
  • 创建其他应用或其他Module的Context
  • 订阅进程内Ability生命周期变化

获取应用文件路径

基类Context提供了获取应用文件路径的能力,ApplicationContext、AbilityStageContext、UIAbilityContext和ExtensionContext均继承该能力。应用文件路径属于应用沙箱路径,具体请参见应用沙箱目录。

上述各类Context获取的应用文件路径有所不同。

  • 通过ApplicationContext获取应用级别的应用文件路径,此路径是应用全局信息推荐的存放路径,这些文件会跟随应用的卸载而删除。

    属性路径
    bundleCodeDir<路径前缀>/el1/bundle/
    cacheDir<路径前缀>/<加密等级>/base/cache/
    filesDir<路径前缀>/<加密等级>/base/files/
    preferencesDir<路径前缀>/<加密等级>/base/preferences/
    tempDir<路径前缀>/<加密等级>/base/temp/
    databaseDir<路径前缀>/<加密等级>/database/
    distributedFilesDir<路径前缀>/el2/distributedFiles/
  • 通过AbilityStageContext、UIAbilityContext、ExtensionContext获取HAP级别的应用文件路径。此路径是HAP相关信息推荐的存放路径,这些文件会跟随HAP的卸载而删除,但不会影响应用级别路径的文件,除非该应用的HAP已全部卸载。

    属性路径
    bundleCodeDir<路径前缀>/el1/bundle/
    cacheDir<路径前缀>/<加密等级>/base/haps//cache/
    filesDir<路径前缀>/<加密等级>/base/haps//files/
    preferencesDir<路径前缀>/<加密等级>/base/haps//preferences/
    tempDir<路径前缀>/<加密等级>/base/haps//temp/
    databaseDir<路径前缀>/<加密等级>/database//
    distributedFilesDir<路径前缀>/el2/distributedFiles//

示例代码如下。

import UIAbility from '@ohos.app.ability.UIAbility';export default class EntryAbility extends UIAbility {onCreate(want, launchParam) {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;// ...}
}

获取和修改加密分区

上一个场景中,引入了加密等级的概念,通过对Context的area属性的读写来实现获取和设置当前加密分区,支持如下两种加密等级:

  • AreaMode.EL1:设备级加密区,设备开机后可访问的数据区。
  • AreaMode.EL2:用户级加密区,设备开机,首次输入密码后才能够访问的数据区。
import UIAbility from '@ohos.app.ability.UIAbility';export default class EntryAbility extends UIAbility {onCreate(want, launchParam) {// 存储普通信息前,切换到EL1设备级加密if (this.context.area === 1) { // 获取areathis.context.area = 0;     // 修改area}// 存储普通信息// 存储敏感信息前,切换到EL2用户级加密if (this.context.area === 0) { // 获取areathis.context.area = 1;     // 修改area}// 存储敏感信息}
}

创建其他应用或其他Module的Context

基类Context提供创建其他应用或其他Module的Context的方法为createModuleContext(moduleName:string),创建其他应用或者其他Module的Context,从而通过该Context获取相应的资源信息(例如获取其他Module的获取应用开发路径信息)。

调用createModuleContext(moduleName:string)方法,获取本应用中其他Module的Context。获取到其他Module的Context之后,即可获取到相应Module的资源信息。

import UIAbility from '@ohos.app.ability.UIAbility';export default class EntryAbility extends UIAbility {onCreate(want, launchParam) {let moduleName2 = "module1";let context2 = this.context.createModuleContext(moduleName2);// ...}
}

订阅进程内Ability生命周期变化

在应用内的DFX统计场景,如需要统计对应页面停留时间和访问频率等信息,可以使用订阅进程内Ability生命周期变化功能。

在进程内Ability生命周期变化时,如创建、可见/不可见、获焦/失焦、销毁等,会触发进入相应的回调,其中返回的此次注册监听生命周期的ID(每次注册该ID会自增+1,当超过监听上限数量2^63-1时,返回-1),以在UIAbilityContext中使用为例进行说明。

import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';const TAG: string = "[Example].[Entry].[EntryAbility]";export default class EntryAbility extends UIAbility {lifecycleId: number;onCreate(want, launchParam) {let abilityLifecycleCallback = {onAbilityCreate(ability) {console.info(TAG, "onAbilityCreate ability:" + JSON.stringify(ability));},onWindowStageCreate(ability, windowStage) {console.info(TAG, "onWindowStageCreate ability:" + JSON.stringify(ability));console.info(TAG, "onWindowStageCreate windowStage:" + JSON.stringify(windowStage));},onWindowStageActive(ability, windowStage) {console.info(TAG, "onWindowStageActive ability:" + JSON.stringify(ability));console.info(TAG, "onWindowStageActive windowStage:" + JSON.stringify(windowStage));},onWindowStageInactive(ability, windowStage) {console.info(TAG, "onWindowStageInactive ability:" + JSON.stringify(ability));console.info(TAG, "onWindowStageInactive windowStage:" + JSON.stringify(windowStage));},onWindowStageDestroy(ability, windowStage) {console.info(TAG, "onWindowStageDestroy ability:" + JSON.stringify(ability));console.info(TAG, "onWindowStageDestroy windowStage:" + JSON.stringify(windowStage));},onAbilityDestroy(ability) {console.info(TAG, "onAbilityDestroy ability:" + JSON.stringify(ability));},onAbilityForeground(ability) {console.info(TAG, "onAbilityForeground ability:" + JSON.stringify(ability));},onAbilityBackground(ability) {console.info(TAG, "onAbilityBackground ability:" + JSON.stringify(ability));},onAbilityContinue(ability) {console.info(TAG, "onAbilityContinue ability:" + JSON.stringify(ability));}}// 1. 通过context属性获取applicationContextlet applicationContext = this.context.getApplicationContext();// 2. 通过applicationContext注册监听应用内生命周期this.lifecycleId = applicationContext.on("abilityLifecycle", abilityLifecycleCallback);console.info(TAG, "register callback number: " + JSON.stringify(this.lifecycleId));}onDestroy() {let applicationContext = this.context.getApplicationContext();applicationContext.off("abilityLifecycle", this.lifecycleId, (error, data) => {console.info(TAG, "unregister callback success, err: " + JSON.stringify(error));});}
}

相关文章:

  • gookit/color - Go语言命令行色彩使用库教程
  • sql:定时执行存储过程(嵌套存储过程、使用游标)
  • 算法训练营第三十天|332.重新安排行程 51. N皇后 37. 解数独
  • 202402读书笔记|《当你老了》——灰蒙曙光比爱情温柔,清晨露珠比希望更可爱
  • 如何实现服务器主动向客户端推送实时数据
  • CSS尺寸单位详解(rpx、px、pt、em、rem、%、vh、vw的区别)
  • pod 基础 2
  • 惠普83752A合成扫频器/信号源0.01-20GHz
  • imgaug库指南(四):从入门到精通的【图像增强】之旅
  • flutter学习-day22-使用GestureDetector识别手势事件
  • 使用react+vite开发项目时候,部署上线后刷新页面无法访问解决办法
  • 【响应式编程-03】Lambda表达式底层实现原理
  • 【INTEL(ALTERA)】Intel Agilex7 设备的外设图像比特流大小是多少?
  • Kafka集群详解
  • 电缆厂 3D 可视化管控系统 | 图扑数字孪生
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • 78. Subsets
  • Android组件 - 收藏集 - 掘金
  • CEF与代理
  • fetch 从初识到应用
  • SpringBoot几种定时任务的实现方式
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 开源SQL-on-Hadoop系统一览
  • 前端面试总结(at, md)
  • 如何合理的规划jvm性能调优
  • 微服务框架lagom
  • 责任链模式的两种实现
  • 阿里云ACE认证学习知识点梳理
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • #mysql 8.0 踩坑日记
  • #QT(智能家居界面-界面切换)
  • (2015)JS ES6 必知的十个 特性
  • (JS基础)String 类型
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • .Net IOC框架入门之一 Unity
  • .NET Standard 支持的 .NET Framework 和 .NET Core
  • .NET 中创建支持集合初始化器的类型
  • .NET8.0 AOT 经验分享 FreeSql/FreeRedis/FreeScheduler 均已通过测试
  • .Net的DataSet直接与SQL2005交互
  • .Net下C#针对Excel开发控件汇总(ClosedXML,EPPlus,NPOI)
  • .net下简单快捷的数值高低位切换
  • [ C++ ] STL---stack与queue
  • [<MySQL优化总结>]
  • [acwing周赛复盘] 第 69 场周赛20220917
  • [AIGC] Kong:一个强大的 API 网关和服务平台
  • [C#]OpenCvSharp使用帧差法或者三帧差法检测移动物体
  • [C++]AVL树怎么转
  • [CC2642r1] ble5 stacks 蓝牙协议栈 介绍和理解
  • [CQOI 2010]扑克牌
  • [docker]docker网络-直接路由模式
  • [echarts] y轴不显示0
  • [Fri 26 Jun 2015 ~ Thu 2 Jul 2015] Deep Learning in arxiv
  • [java面试]宇信易诚 广州分公司 java笔试题目回忆录