赞
踩
AbilityStage是一个Module级别的组件容器,应用的HAP在首次加载时会创建一个AbilityStage实例,可以对该Module进行初始化等操作。
AbilityStage与Module一一对应,即一个Module拥有一个AbilityStage。
DevEco Studio默认工程中未自动生成AbilityStage,如需要使用AbilityStage的能力,可以手动新建一个AbilityStage文件,具体步骤如下。
在工程Module对应的ets目录下,右键选择“New > Directory”,新建一个目录并命名为myabilitystage。
在myabilitystage目录,右键选择“New > TypeScript File”,新建一个TypeScript文件并命名为MyAbilityStage.ts。
打开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";
}
}
{
"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是应用中对象的上下文,其提供了应用的一些基础信息,例如resourceManager(资源管理)、applicationInfo(当前应用信息)、dir(应用开发路径)、area(文件分区)等,以及应用的一些基本方法,例如createBundleContext()、getApplicationContext()等。UIAbility组件和各种ExtensionAbility派生类组件都有各自不同的Context类。分别有基类Context、ApplicationContext、AbilityStageContext、UIAbilityContext、ExtensionContext、ServiceExtensionContext等Context。
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let uiAbilityContext = this.context;
// ...
}
}
import AbilityStage from "@ohos.app.ability.AbilityStage";
export default class MyAbilityStage extends AbilityStage {
onCreate() {
let abilityStageContext = this.context;
// ...
}
}
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let applicationContext = this.context.getApplicationContext();
// ...
}
}
基类Context提供了获取应用文件路径的能力,ApplicationContext、AbilityStageContext、UIAbilityContext和ExtensionContext均继承该能力。应用文件路径属于应用沙箱路径,具体请参见应用沙箱目录。
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) { // 获取area this.context.area = 0; // 修改area } // 存储普通信息 // 存储敏感信息前,切换到EL2用户级加密 if (this.context.area === 0) { // 获取area this.context.area = 1; // 修改area } // 存储敏感信息 } }
基类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);
// ...
}
}
在应用内的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属性获取applicationContext let 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)); }); } }
Want是对象间信息传递的载体,可以用于应用组件间的信息传递。其使用场景之一是作为startAbility()的参数,包含了指定的启动目标以及启动时需携带的相关数据,如bundleName和abilityName字段分别指明目标Ability所在应用的包名以及对应包内的Ability名称。当UIAbilityA启动UIAbilityB并需要传入一些数据给UIAbilityB时,Want可以作为一个载体将数据传给UIAbilityB。
显式Want:在启动Ability时指定了abilityName和bundleName的Want称为显式Want。
隐式Want:在启动UIAbility时未指定abilityName的Want称为隐式Want。
let wantInfo = {
// uncomment line below if wish to implicitly query only in the specific bundle.
// bundleName: 'com.example.myapplication',
action: 'ohos.want.action.search',
// entities can be omitted
entities: [ 'entity.system.browsable' ],
uri: 'https://www.test.com:8080/query/student',
type: 'text/plain',
};
从隐式Want的定义,可得知:
调用方传入的want参数,表明调用方需要执行的操作,并提供相关数据以及其他应用类型限制。
待匹配Ability的skills配置,声明其具备的能力(module.json5配置文件中的skills标签参数)。
系统将调用方传入的want参数(包含action、entities、uri和type属性)与已安装待匹配的应用Ability的skills配置(包含actions、entities、uris和type属性)依次进行匹配。当四个属性匹配均通过,则此应用才会被应用选择器展示给用户进行选择。
将调用方传入的want参数的action与待匹配Ability的skills配置中的actions进行匹配。
调用方传入的want参数的action为空,待匹配Ability的skills配置中的actions为空,则action匹配失败。
调用方传入的want参数的action不为空,待匹配Ability的skills配置中的actions为空,则action匹配失败。
调用方传入的want参数的action为空,待匹配Ability的skills配置中的actions不为空,则action匹配成功。
调用方传入的want参数的action不为空,待匹配Ability的skills配置中的actions不为空且包含调用方传入的want参数的action,则action匹配成功。
调用方传入的want参数的action不为空,待匹配Ability的skills配置中的actions不为空且不包含调用方传入的want参数的action,则action匹配失败。
将调用方传入的want参数的entities与待匹配Ability的skills配置中的entities进行匹配。
调用方传入的want参数的entities为空,待匹配Ability的skills配置中的entities不为空,则entities匹配成功。
调用方传入的want参数的entities为空,待匹配Ability的skills配置中的entities为空,则entities匹配成功。
调用方传入的want参数的entities不为空,待匹配Ability的skills配置中的entities为空,则entities匹配失败。
调用方传入的want参数的entities不为空,待匹配Ability的skills配置中的entities不为空且包含调用方传入的want参数的entities,则entities匹配成功。
调用方传入的want参数的entities不为空,待匹配Ability的skills配置中的entities不为空且不完全包含调用方传入的want参数的entities,则entities匹配失败。
调用方传入的want参数中设置uri和type参数发起组件启动请求,系统会遍历当前系统已安装的组件列表,并逐个匹配待匹配Ability的skills配置中的uris数组,如果待匹配Ability的skills配置中的uris数组中只要有一个可以匹配调用方传入的want参数中设置的uri和type即为匹配成功。
want参数中uri和type皆不为空时的匹配规则
实际应用中,uri和type共存在四种情况,下面将讲解四种情况的具体匹配规则:
调用方传入的want参数的uri和type都为空。
a. 如果待匹配Ability的skills配置中的uris数组为空,匹配成功。
b. 如果待匹配Ability的skills配置中的uris数组中存在uri的scheme和type都为空的元素,匹配成功。
c. 除以上两种情况,其他情况均为匹配失败。
调用方传入的want参数的uri不为空,type为空。
a. 如果待匹配Ability的skills配置中的uris数组为空,匹配失败。
b. 如果待匹配Ability的skills配置中的uris数组存在一条数据uri匹配成功且type为空,则匹配成功,否则匹配失败。
调用方传入的want参数的uri为空,type不为空。
a. 如果待匹配Ability的skills配置中的uris数组为空,匹配失败。
b. 如果待匹配Ability的skills配置中的uris数组存在一条数据uri的scheme为空且type匹配成功,则匹配成功,否则匹配失败。
调用方传入的want参数的uri和type都不为空,如上图所示。
a. 如果待匹配Ability的skills配置中的uris数组为空,匹配失败。
b. 如果待匹配Ability的skills配置中的uris数组存在一条数据uri匹配和type匹配需要均匹配成功,则匹配成功,否则匹配失败。
为了简化描述,称want中传入的uri为w_uri,称want中传入的type为w_type, 待匹配Ability的skills配置中uris为s_uris,其中每个元素为s_uri;按自上而下顺序匹配。
这里为了简化描述,称want中传入的uri为w_uri,待匹配Ability的skills配置中uri为s_uri,具体的匹配规则如下:
如果s_uri的scheme为空,当w_uri为空时匹配成功,否则匹配失败;
如果s_uri的host为空,当w_uri和s_uri的scheme相同时匹配成功,否则匹配失败;
如果s_uri的path、pathStartWith和pathRegex都为空,当w_uri和s_uri完全相同时匹配成功,否则匹配失败;
如果s_uri的path不为空,当w_uri和s_uri全路径表达式相同时匹配成功,否则继续进行pathStartWith的匹配;
如果s_uri的pathStartWith不为空,当w_uri包含s_uri前缀表达式时匹配成功,否则继续进行pathRegex的匹配;
如果s_uri的pathRegex不为空,当w_uri满足s_uri正则表达式时匹配成功,否则匹配失败;
此小节所述的type匹配规则的适用性需建立在want参数内type不为空的基础上。当want参数内type为空时请参考want参数的uri和type匹配规则。
这里为了简化描述,称want中传入的uri为w_type,待匹配Ability的skills数组中uris的type数据为s_type,具体的匹配规则如下:
如果s_type为空,则匹配失败。
如果s_type或者w_type为通配符"/",则匹配成功。
如果s_type最后一个字符为通配符’',如"prefixType/",则当w_type包含"prefixType/"时匹配成功,否则匹配失败。
如果w_type最后一个字符为通配符’',如"prefixType/",则当s_type包含"prefixType/"时匹配成功,否则匹配失败。
ACTION_HOME:启动应用入口组件的动作,需要和ENTITY_HOME配合使用;系统桌面应用图标就是显式的入口组件,点击也是启动入口组件;入口组件可以配置多个。
ACTION_CHOOSE:选择本地资源数据,例如联系人、相册等;系统一般对不同类型的数据有对应的Picker应用,例如联系人和图库。
ACTION_VIEW_DATA:查看数据,当使用网址uri时,则表示显示该网址对应的内容。
ACTION_VIEW_MULTIPLE_DATA:发送多个数据记录的操作。
entities:表示目标Ability的类别信息(如浏览器、视频播放器),在隐式Want中是对action的补充。在隐式Want中,开发者可定义该字段,来过滤匹配应用的类别,例如必须是浏览器。在Want内声明entities字段表示希望被调用方应用属于声明的类别。在被调用方应用配置文件skills字段内声明entites表示该应用支持的类别。
ENTITY_DEFAULT:默认类别无实际意义。
ENTITY_HOME:主屏幕有图标点击入口类别。
ENTITY_BROWSABLE:指示浏览器类别。
import common from '@ohos.app.ability.common'; // ... async explicitStartAbility() { try { // Explicit want with abilityName specified. let want = { deviceId: "", bundleName: "com.example.myapplication", abilityName: "calleeAbility" }; let context = getContext(this) as common.UIAbilityContext; await context.startAbility(want); console.info(`explicit start ability succeed`); } catch (error) { console.info(`explicit start ability failed with ${error.code}`); } } // ...
async implicitStartAbility() { try { let want = { // uncomment line below if wish to implicitly query only in the specific bundle. // bundleName: "com.example.myapplication", "action": "ohos.want.action.viewData", // entities can be omitted. "entities": [ "entity.system.browsable" ], "uri": "https://www.test.com:8080/query/student", "type": "text/plain" } let context = getContext(this) as common.UIAbilityContext; await context.startAbility(want) console.info(`explicit start ability succeed`) } catch (error) { console.info(`explicit start ability failed with ${error.code}`) } }
import wantConstant from '@ohos.ability.wantConstant'; // let path = ... // let fileFd = ... // let fileSize = ... let want = { // This action is used to implicitly match the application selctor. action: wantConstant.Action.ACTION_SELECT, // This is the custom parameter in the first layer of want // which is intended to add info to application selector. parameters: { // The MIME type of pdf "ability.picker.type": "application/pdf", "ability.picker.fileNames": [path], "ability.picker.fileSizes": [fileSize], // This a nested want which will be directly send to the user selected application. "ability.want.params.INTENT": { "action": "ohos.want.action.sendData", "type": "application/pdf", "parameters": { "keyFd": {"type": "FD", "value": fileFd} } } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。