文章目录
一、前言
UIAbility
组件是一种包含UI界面的应用组件,主要用于和用户交互。
UIAbility
组件是系统调度的基本单元,为应用提供绘制界面的窗口;一个UIAbility
组件中可以通过多个页面来实现一个功能模块。每一个UIAbility
组件实例,都对应于一个最近任务列表中的任务。
UIAbility
组件就像手机上的一个应用,它负责展示应用的用户界面,用户可以通过它来和应用进行互动。每个UIAbility
组件可以包含多个不同的界面,就像应用中的不同页面。用户每次在手机上打开一个应用,实际上是启动了一个UIAbility
组件的实例,这个应用会在最近任务列表中显示。这个机制让用户能够轻松切换和管理不同应用和它们的界面。
为使应用能够正常使用UIAbility
,需要在module.json5
配置文件的abilities
标签中声明UIAbility
的名称、入口、标签等相关信息。
以下为设置的UIAbility
参数:
typescript
{
"module": {
// ...
"abilities": [
{
"name": "EntryAbility", // UIAbility组件的名称
"srcEntrance": "./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组件启动页面背景颜色资源文件的索引
// ...
}
]
}
}
二、UIAbility 组件生命周期
UIAbility
就像是应用中的一个窗口或界面,拥有自己的生命周期,就像一个角色有不同的状态。这个生命周期包括创建/销毁/前台/后台四个状态:
-
Create
(创建):当用户打开应用或者切换到应用时,UIAbility
被创建。例如用户打开一个应用,应用的界面被呈现在屏幕上。 -
Foreground
(前台):当应用界面处于活跃状态时,它处于前台状态。例如用户正在使用一个应用,它是当前的焦点。 -
Background
(后台):如果你切换到了其他应用,原来的应用就进入了后台状态。UIAbility
也会相应地从前台变成后台状态。 -
Destroy
(销毁):当用户关闭应用或者应用被系统销毁时,UIAbility
也会被销毁。例如用户关闭一个应用,它的界面消失了。
这些状态变化可以帮助应用了解UIAbility
在不同时刻的状态,从而执行不同的操作或者保持应用的一致性。
四种声明周期间的转换方式可以用以下流程图表示。
实际项目中,在EntryAbility.ts
文件内容定义如下:
typescript
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
}
onDestroy(): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err) => {
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.');
});
}
onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground(): void {
// Ability has brought to foreground
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground(): void {
// Ability has back to background
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
}
}
其中,Create
状态为在应用加载过程中,UIAbility
实例创建完成时触发,系统会调用onCreate()
回调。可以在该回调中进行应用初始化操作,例如变量定义资源加载等,用于后续的UI界面展示。
每个UIAbility
类实例都会与一个WindowStage
类实例绑定,WindowStage
类起到了应用进程内窗口管理器的作用,它包含一个主窗口。也就是说,UIAbility
通过WindowStage
持有了一个窗口,该窗口为ArkUI
提供了绘制区域。
可以理解为当应用程序启动时,系统会自动为每个UIAbility
实例创建一个WindowStage
(窗口舞台)。这个WindowStage
就像是应用界面的舞台,上面可以加应用需要的各种UI元素。
根据鸿蒙开发应用的stage
开发模型工作原理,UIAbility
组件生命周期回调函数及WindowStage
回调函数间的流转方式如下图所示:
在WindowStage
创建完成后,系统会调用onWindowStageCreate()
回调函数。在这个函数里,开发者可以设置所需的UI界面,比如加载各种页面,设置UI元素的样式等。还可以订阅WindowStage
事件,比如获得焦点(用户正在与应用交互)或失去焦点(应用不再是用户的焦点)、可见或不可见等。这些事件让应用能够响应用户的操作。
在onWindowStageCreate()
回调函数中,通常会使用loadContent()
方法来加载应用要显示的页面。同时,也可以根据需要订阅各种WindowStage
事件,以便在用户操作发生时做出相应的响应。
当用户退出应用或者应用被系统销毁时,对应的UIAbility
实例会被销毁。在这之前,系统会先调用onWindowStageDestroy()
回调函数。在这个函数里,可以释放UI界面所占用的资源,做一些清理工作。比如,可以在这里注销之前订阅的获得焦点或失去焦点等WindowStage
事件,以确保资源被正确释放,应用退出时不会出现问题。
这样,通过在WindowStage
的创建和销毁过程中设置相应的回调函数,使得应用就能够在不同的阶段执行不同的操作,从而保证用户体验的一致性和应用的稳定性。
Foreground
和Background
状态分别在UIAbility实例切换至前台和切换至后台时触发,对应于onForeground()
回调和onBackground()
回调。
onForeground()
回调,在UIAbility
的UI界面可见之前,如UIAbility
切换至前台时触发。可以在onForeground()
回调中申请系统需要的资源,或者重新申请在onBackground()
中释放的资源。
onBackground()
回调,在UIAbility
的UI界面完全不可见之后,如UIAbility
切换至后台时候触发。可以在onBackground()
回调中释放UI界面不可见时无用的资源,或者在此回调中执行较为耗时的操作,例如状态保存等。
例如应用在使用过程中需要使用用户定位时,假设应用已获得用户的定位权限授权。在UI界面显示之前,可以在onForeground()
回调中开启定位功能,从而获取到当前的位置信息。
当应用切换到后台状态,可以在onBackground()
回调中停止定位功能,以节省系统的资源消耗。
注意⚠️:预览模式是查看不了onForeground()
、onBackground()
这两个回调函数执行的。
Destroy
状态在UIAbility
实例销毁时触发。可以在onDestroy()
回调中进行系统资源的释放、数据的保存等操作。
例如调用terminateSelf()
方法停止当前UIAbility
实例,从而完成UIAbility
实例的销毁;或者用户使用最近任务列表关闭该UIAbility
实例,完成UIAbility
的销毁。
三、UIAbility 组件启动模式
UIAbility
的启动模式是指UIAbility
实例在启动时的不同呈现状态。针对不同的业务场景,系统提供了三种启动模式:
singleton
(单实例模式)standard
(标准实例模式)specified
(指定实例模式)
通过在module.json5
配置文件中的"launchType
"字段配置为singleton
、standard
、specified
即可。
typescript
{
"module": {
// ...
"abilities": [
{
"launchType": "multiton", // 支持配置为singleton、standard、specified三种启动模式
// ...
}
]
}
}
3.1 singleton 单实例启动模式
Singleton
启动模式是一种应用程序的启动方式,通常是默认的启动方式。在这个模式下,当使用startAbility()
方法来启动一个UIAbility
时,如果已经存在相同类型的UIAbility
实例,系统会复用现有的实例,而不会创建新的,此时只会进入该UIAbility
的onNewWant()
回调,不会进入其onCreate()
和onWindowStageCreate()
生命周期回调。这意味着在最近任务列表中,只会存在一个该类型的UIAbility
实例。
就好像有一个应用,当多次打开同一功能页面时,不会每次打开都创建新的页面,而是会重新使用已经存在的页面。这样可以节省系统资源,提高应用的运行效率,而且在最近任务列表中只会看到一个相同类型的页面。这个模式通常用于确保应用不会出现大量相同的界面实例,以提供更好的用户体验和系统性能。
3.2 standard 标准实例启动模式
standard
启动模式为标准实例模式,每次调用startAbility()
方法时,都会在应用进程中创建一个新的该类型UIAbility
实例。即在最近任务列表中可以看到有多个该类型的UIAbility
实例。
3.3 specified 指定实例启动模式
Specified
启动模式是一种特殊的启动模式,通常用于特定场景,比如文档编辑应用。它允许开发者在创建UIAbility
实例之前为该实例指定一个唯一的标识字符串(称为Key)。当UIAbility
实例与这个Key绑定之后,在后续调用startAbility()
方法时,系统会询问应用要打开哪个与特定Key绑定的UIAbility
实例。
这种方式可以理解为每个UIAbility
实例都有一个特定的身份标识(Key)。每次开发者启动UIAbility
时,系统会根据这个Key来判断是复用已存在的特定Key绑定的UIAbility
实例,还是创建一个新的实例。例如,在文档编辑应用中,如果想新建一个文档,可以使用一个新的Key,这将创建一个新的UIAbility
实例;但如果想打开一个已保存的文档,可以使用该文档对应的Key,这将打开与之绑定的已存在的UIAbility
实例。
所以,这种模式允许应用在运行时根据特定的Key来决定是否创建新实例或复用已有实例,以便满足不同的业务需求,比如确保每个文档有自己独立的编辑界面或者确保打开相同文档时共享同一个界面。
若UIAbility
配置为指定实例模式,再次调用startAbility()
方法启动该UIAbility
实例,且AbilityStage
的onAcceptWant()
回调匹配到一个已创建的UIAbility
实例。此时,再次启动该UIAbility
时,只会进入该UIAbility
的onNewWant()
回调,不会进入其onCreate()
和onWindowStageCreate()
生命周期回调。