#HarmonyOS NEXT体验官# 鸿蒙应用开发-你不得不知道的UIAbility组件 原创
UIAbility概念
鸿蒙应用是基于Ability
组件来开发的,UIAbility
是Ability
类型中的一种,是带有UI类型的Ability
,为应用提供window窗口绘制以及交互。
每一个UIAbility
实例,都对应于一个最近任务列表中的任务。一个UIAbility
可以对应于多个页面,建议将一个独立的功能模块放到一个UIAbility
中。
Router - UIAbility内的页面跳转
我们指定一个UIAbility可以有多个Page页面。启动一个Page是通过router
来完成的。
router.pushUrl
// 在单例模式下,若栈中存在改实例,则会将实例移至栈顶,栈数量是不变的,若栈中不存在改实例,改实例则会入栈顶,栈数量+1
// 在标准模式(多实例)下,无论栈中是否存在实例,都会将新页面实例加入栈顶,栈数量+1
router.pushUrl({ url: RouteConstants.RANK_PAGE_URL,
params: { src: "main page push 传来的数据" } },
router.RouterMode.Single
)
url
:页面路径params
:跳转携带的参数mode
:启动模式Single
:单例模式- 在单例模式下,若栈中存在改实例,则会将实例移至栈顶,栈数量是不变的,若栈中不存在改实例,改实例则会入栈顶,栈数量+1
Standard
:多实例模式- 在标准模式(多实例)下,无论栈中是否存在实例,都会将新页面实例加入栈顶,栈数量+1
页面路径需要在resources/profile/main_pages.json文件
中注册。在目标页面接收参数,可以在aboutToAppear
接受参数。
aboutToAppear() {
// 实战中最好对参数属性判空,避免闪退
let src = router.getParams()['src']
LogUtils.d(src)
LogUtils.d("stack size: "+router.getLength())
}
返回上一页或返回指定页面,也是可以携带参数返回的。
// 返回上一页
router.back()
// 返回指定页
router.back({ url: RouteConstants.EXAMPLE_MAIN_PAGE_URL, params: { src: "来自上页的数据" } })
当返回有携带参数时,可以在目标组件页面的onPageShow()
方法来接收,如下:
onPageShow() {
// 页面显示时被调用
// 初次创建页面时、从后台进入前台时
LogUtils.d("onPageShow")
LogUtils.d("stack size: " + router.getLength())
// 接受上页返回携带的数据,注意需要判空,不然会闪退
if (router.getParams() != null ) {
let params = (router.getParams() as Record<string, string>)
LogUtils.d("scr: " + params.src)
}
}
router.replaceUrl
router.replaceUrl
的参数是与router.pushUrl
是一样的,区别是启动模式的表现。
// 在单例模式下,若栈中存在实例,则会将栈顶的实例移出栈,然后将目标实例移至栈顶,栈数据-1,若栈中不存在实例,则新实例入栈顶替换原来栈顶的实例,栈数量不变
// 在标准模式(多实例)下,无论栈中是否存在实例,都会将新页面实例加入栈顶并替换原栈顶实例,栈数量不变
router.replaceUrl({ url: RouteConstants.RANK_PAGE_URL, params: { src: "main page replace 传来的数据" } })
- 单例模式下,若栈中存在实例,则会将栈顶的实例移出栈,然后将目标实例移至栈顶,栈数据-1,若栈中不存在实例,则新实例入栈顶替换原来栈顶的实例,栈数量不变。
- 标准模式(多实例)下,无论栈中是否存在实例,都会将新页面实例加入栈顶并替换原栈顶实例,栈数量不变。
由于当前页被替换了,因此在返回时携带参数是无效的,无法接收的。
UIAbility生命周期
从桌面点击打开应用,或者返回桌面等操作,UIAbility
的生命周期都会发生变化。
export default class EntryAbility extends UIAbility {
/**
* 1、UIAbility实例创建时,系统会回调onCreate方法,UI不可见
* 可以用于sdk的初始化,类似于Android的Application#onCreate()方法
* @param want
* @param launchParam
*/
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
}
/**
* 6、在UIAbility销毁时触发。可以在onDestroy回调中进行系统资源的释放、数据的保存等操作。
*/
onDestroy(): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
}
/**
* 2、在创建UIAbility实例后,进入前台前,系统会创建一个WindowStage,然后回调onWindowStageCreate方法
* 可以用于UI页面加载、设置WindowStage的事件订阅,其中入口页面就是在这里设置的,通过WindowStage#loadContent
* 一个UIAbility只有一个WindowStage,
* @param windowStage
*/
onWindowStageCreate(windowStage: window.WindowStage): void {
// 根页面组件就是在完成加载的
windowStage.loadContent("pages/LoginPage", (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) ?? '');
});
}
/**
* 5、在UIAbility实例销毁之前,则会先进入onWindowStageDestroy回调,我们可以在该回调中释放UI页面资源。
*/
onWindowStageDestroy(): void {
}
/**
* 3、从后台(桌面、任务栏)切换到前台,ui可见
* 可以向系统申请需要的资源,比如定位、播放视频
*/
onForeground(): void {
}
/**
* 4、从前台切换到后台,ui不可见
* 可以释放一些资源,比如停止定位,暂停播放视频
*/
onBackground(): void {
}
}
用户使用应用的程序退出功能,会调用
UIAbilityContext
的terminalSelf()
方法,从而完成UIAbility
销毁。或者用户使用最近任务列表关闭该UIAbility
实例时,也会完成UIAbility
的销毁。
UIAbility的启动模式及交互
UIAbility
三种启动模式:
singleton
(单实例模式):默认模式,每次调用startAbility()
启动UIAbility
时,如果应用进程中该类型的UIAbility
实例已经存在,则复用系统中的UIAbility
实例,系统中只存在唯一一个该UIAbility
实例。multiton
(多实例模式):每次调用startAbility()
方法时,都会在应用进程中创建一个该类型的UIAbility
实例。specified
(指定实例模式):根据业务需要是否创建一个新的UIAbility
实例。
启动UIAbility的基本使用:
一、在module.json5
注册UIAbility
组件
// 注册UIAbility
{
"name":"LaunchModeAbility",
"icon": "$media:ic_registration_success",
"label": "$string:ability_test_name",
"srcEntry": "./ets/ability/LaunchModeAbility.ets",
"startWindowIcon": "$media:ic_registration_success",
"startWindowBackground": "$color:start_window_background",
// 启动模式
"launchType": "singleton"
}
name
: 名称,尽量与类名一样icon
:图标,在后台任务栏的可以看到label
:UIAbility的名称srcEntry
:UIAbility的相对路径launchType
:启动模式
二、启动UIAbility
通过UIAbilityContext
来调用startAbility()
方法来启动。
private context = getContext(this) as common.UIAbilityContext
...
// 启动
let want = {
bundleName:"com.xxxx.demo",
abilityName:"LaunchModeAbility",
moduleName:"entry",
parameters: { src: "main page param " + this.counter }
}
this.context.startAbility(want)
bundleName
:UIAbility
所在应用的包名abilityName
:UIAbility
名称moduleName
:UIAbility
所在模块的名称parameters
:启动携带的参数,可以在UIAbility
的onCreate()
中接收。
Want实例不能通过new的方式来创造,因为没有默认的构造函数,只能通过字面量的方式来定义的一个实例。
三、接收启动的参数
export default class LaunchModeAbility extends UIAbility{
static readonly TAG:string = "LaunchModeAbility"
onCreate(want: Want, param: AbilityConstant.LaunchParam){
// 接收传递的参数
let src = want.parameters.src
LogUtils.d("LaunchModeAbility onCreate src: "+src)
}
onDestroy(){
LogUtils.d("LaunchModeAbility onDestroy")
}
onWindowStageCreate(windowStage: window.WindowStage) {
LogUtils.d("onWindowStageCreate")
// 加载根页面组件
windowStage.loadContent(RouteConstants.TEST_PAGE_URL, (error, data) => {
if (error.code) {
LogUtils.e(error.message)
}
})
}
}
推荐
这样推荐一个页面导航库: