前文提到过,在使用DevEco创建鸿蒙项目的时候,会选择Empty Ability,那么这个Ability是什么呢?其实对比Android Studio创建Android羡慕时选择的Empty Activity,感觉Harmony的Ability更像是Android的Activity,但只能说像,不完全等同。本篇,我们就基于API9一起探索下UIAbility。因为本人是Android开发者,所以文章中会时不时的跟Android对比。
鸿蒙系列上一篇
鸿蒙开发(二)鸿蒙DevEco3.X开发环境搭建-CSDN博客文章浏览阅读1k次,点赞13次,收藏19次。上篇说到,鸿蒙开发目前势头旺盛,头部大厂正在如火如荼地进行着,华为也对外宣称已经跟多个厂商达成合作。目前看来,对于前端或客户端开发人员来说,掌握下鸿蒙开发还是有些必要性的。如果你之前是从事Android开发的,那么你会发现除了开发语言,鸿蒙基本上就跟Android一模一样。在正式进行鸿蒙开发前,首先是搭建DevEco开发环境,本篇介绍下如何基于DevEco3.X搭建鸿蒙开发环境并且运行第一行代码-Hello World。https://blog.csdn.net/qq_21154101/article/details/135215940?spm=1001.2014.3001.5501
目录
一、UIAbility概述
二、UIAbility生命周期
1、生命周期概述
2、onCreate
3、onWindowStageCreate和onWindowStageDestroy
4、 onForeground和onBackground
onForeground()回调,在UIAbility实例切换至前台时触发,在UIAbility的UI界面可见之前调用。onBackground()回调,在UIAbility实例切换至后台时候触发,在UIAbility的UI界面完全不可见之后调用。
5、 onDestroy
三、UIAbility启动模式
1、 singleton启动模式
2、 standard启动模式
3、 specified启动模式
四、UIAbility组件间交互
1、创建UIAbility
2、创建页面
3、绑定UIAbility和页面
一、UIAbility概述
在介绍UIAbility之前,我们先看下Ability,Ability直译过来就是能力。什么能力呢?引用官方开发者社区对Ability的解释:
Ability是应用/服务所具备的能力的抽象,一个Module可以包含一个或多个Ability。应用/服务先后提供了两种应用模型:
可以看到,Ability是应用/服务所具备的能力的抽象。Stage模型的Ability是主流,因此,本篇我们也基于Stage模型下,对UIAbility进行讲解。
UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个UIAbility组件中可以通过多个页面来实现一个功能模块。
需要注意的是:
每一个UIAbility组件实例,都对应于一个最近任务列表中的任务。
因此,对于开发者而言,可以根据具体的场景选择单个还是多个UIAbility。
二、UIAbility生命周期
上面也多次提到过,UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。既然是包含了跟用户交互的UI界面的应用组件,那么肯定就离不开生命周期。即UIAbility从创建到跟用户交互到最终销毁的整个过程。接下来探索下UIAbility的生命周期。
1、生命周期概述
当用户打开、切换和返回到对应应用时,应用中的UIAbility实例会在其生命周期的不同状态之间转换。UIAbility类提供了一系列回调,通过这些回调可以知道当前UIAbility实例的某个状态发生改变,会经过UIAbility实例的创建和销毁,或者UIAbility实例发生了前后台的状态切换。
UIAbility的生命周期包括onCreate、onForeground、onBackground、onDestroy四个状态,如下图所示:
2、onCreate
onCreate状态为在应用加载过程中,UIAbility实例创建完成时触发,系统会调用onCreate()回调。可以在该回调中进行应用初始化操作,例如变量定义资源加载等,用于后续的UI界面展示。
import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
// 应用初始化
}
// ...
}
3、onWindowStageCreate和onWindowStageDestroy
UIAbility实例创建完成之后,在进入Foreground之前,系统会创建一个WindowStage。WindowStage创建完成后会进入onWindowStageCreate()回调,可以在该回调中通过loadContent()方法设置应用要加载的页面并根据需要订阅WindowStage的事件(获焦/失焦、可见/不可见)。
import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: Window.WindowStage) {
// 设置WindowStage的事件订阅(获焦/失焦、可见/不可见)
// 设置UI界面加载
windowStage.loadContent('pages/Index', (err, data) => {
// ...
});
}
}
同样的,在UIAbility实例销毁之前,则会先进入onWindowStageDestroy()回调,可以在该回调中释放UI界面资源。例如在onWindowStageDestroy()中注销获焦/失焦等WindowStage事件。
import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class EntryAbility extends UIAbility {
// ...
onWindowStageDestroy() {
// 释放UI界面资源
}
}
4、 onForeground和onBackground
onForeground()回调,在UIAbility实例切换至前台时触发,在UIAbility的UI界面可见之前调用。onBackground()回调,在UIAbility实例切换至后台时候触发,在UIAbility的UI界面完全不可见之后调用。
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onForeground() {
// 申请系统需要的资源,或者重新申请在onBackground中释放的资源
}
onBackground() {
// 释放UI界面不可见时无用的资源,或者在此回调中执行较为耗时的操作
// 例如状态保存等
}
}
5、 onDestroy
import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onDestroy() {
// 系统资源的释放、数据的保存等
}
}
三、UIAbility启动模式
同Android的Activity一样,UIAbility也有启动模式。启动模式是指UIAbility实例在启动时的不同呈现状态。针对不同的业务场景,系统提供了三种启动模式:
- singleton启动模式(单实例模式)
- standard启动模式(标准实例模式)
- specified启动模式(指定实例模式)
1、 singleton启动模式
应用的UIAbility实例已创建,该UIAbility配置为单实例模式,再次调用startAbility()方法启动该UIAbility实例,此时只会进入该UIAbility的onNewWant回调,不会进入其onCreate()和onWindowStageCreate()生命周期回调。
如果需要配置单实例模式,module.json5中的"launchType"字段配置为"singleton"即可。
2、 standard启动模式
如果需要配置单实例模式,module.json5中的"launchType"字段配置为"standard"即可。
3、 specified启动模式
四、UIAbility组件间交互
当一个应用内包含多个UIAbility时,存在应用内启动UIAbility的场景。那么,如何在一个UIAbility中启动另一个UIAbility呢?
假设应用中有两个UIAbility:EntryAbility和FuncAbility(可以在应用的一个Module中,也可以在的不同Module中),需要从EntryAbility的页面中启动FuncAbility。
1、创建UIAbility
创建新的UIAbility步骤如下:New -> Ability,跟Android的Activity类似,同时需要在对应的配置文件中进行注册。Android是AndroidManifest.xml文件,而harmony则是module.json5文件。如下图所示,是我创建的一个Demo,默认的EntryAbility继承自UIAbility,声明信息如下:
UIAbility部分声明信息详解(大部分标签不用多解释,跟Android类似):
{
"module": {
// ...
"abilities": [
{
"name": "EntryAbility", // UIAbility组件的名称
"srcEntry": "./ets/entryability/EntryAbility.ts", // UIAbility组件的代码路径
"description": "$string:EntryAbility_desc", // UIAbility组件的描述信息
"icon": "$media:icon", // UIAbility组件的图标
"label": "$string:EntryAbility_label", // UIAbility组件的标签
"startWindowIcon": "$media:icon", // UIAbility组件启动页面图标资源文件的索引
"startWindowBackground": "$color:start_window_background", // UIAbility组件启动页面背景颜色资源文件的索引
"exported": true, // 标识当前UIAbility组件是否可以被其他应用调用
"skills": [ // 标识当前Ability组件能够接收的Want的特征集,为数组格式[类似安卓的IntentFilter]。
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
}
]
}
}
更完整的声明信息见module.json5配置文件
2、创建页面
仅UIAbility也可以,但是没有可展示的页面有点奇奇怪怪。所以,我们给新建的FuncUIAbility创建一个页面Func,代码很简单,直接赋值Index.ets,修改一下message用来区分:
3、绑定UIAbility和页面
这个在讲生命周期的时候说过了,在onWindowStageCreate中调用windowStage.loadContent即可:
onWindowStageCreate(windowStage: window.WindowStage) {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Func', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
注意:需要在resources/profile/main_pages.json中添加新创建的page,,否则UIAbility中无法展示该页面!!!
如下图所示:
4、启动UIAbility
openFuncUiAbility(){
// 调起app内其他的UIAbility
let want: Want = {
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.example.tuduharmonydemo', // 必填
moduleName: '', // moduleName为空表示本模块
abilityName: 'FuncAbility', // 必填
parameters: { // 自定义信息
info: '来自EntryAbility Index页面',
},
}
this.context.startAbility(want).then(() => {
hilog.info(0x0000, this.tag, 'Succeeded in starting ability.');
}).catch((err) => {
hilog.error(0x0000, this.tag, `Failed to start ability. Code is ${err.code}, message is ${err.message}`);
})
}
本篇介绍了UIAbility,包括UIAbility概述、生命周期、启动模式以及UIAbility组件之间的交互。