UIAbility启动模式
什么是UIAbility? UIAbility组件是一种包含UI的应用组件,主要用于和用户交互 。它是HarmonyOS中用于系统调度的基本单元,为应用提供绘制界面的窗口。
其他官方专业数据就不赘述了,简单将就是手机应用里的一个UI窗口。这个类比Android里的Activity,都是UI的应用组件。
官方入口
基础理论
UIAbility类似Android中的Activity,Activity有4中启动模式,而UIAbility有3中启动模式。HarmonyOS中的UIAbility的启动模式相较于Android更加简化易于理解。
- singleton(单实例模式)
当你给UIAbility的launchType
设置为单实例模式,则无论你启动几次该窗口都将仅有一个窗口,多次启动后仅会进入该UIAbility的onNewWant()
回调
- multiton(多实例模式)
多实例模式也是标准模式(standard),标准模式就旧版称呼。多实例模式就是你启动几次UIAbility就会创建几个新的窗口。
- specified(指定实例模式)
specified启动模式为指定实例模式,简单说就是自定义启动模式,是多实例还是单实例你自己来实现
实战说明
我们在刚刚新建的项目上右键创建一个新的UIAbility,起名为SingletonAbility
,点击完成即可。
idea会自动生成一个名为SingletonAbility
的文件,同时将该窗口配置到配置文件中。
同理我们在创建MultitonAbility
和SpecifiedUIAbility
,同时分别设置相应的launchType
...
"abilities": [
...
{
"name": "SingletonAbility",
"srcEntry": "./ets/singletonability/SingletonAbility.ets",
"description": "$string:SingletonAbility_desc",
"icon": "$media:layered_image",
"label": "$string:SingletonAbility_label",
"launchType": "singleton", // 重点这里
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background"
},
{
"name": "MultitonAbility",
"srcEntry": "./ets/multitonability/MultitonAbility.ets",
"description": "$string:MultitonAbility_desc",
"icon": "$media:layered_image",
"label": "$string:MultitonAbility_label",
"launchType": "multiton", // 重点这里
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background"
},
{
"name": "SpecifiedAbility",
"srcEntry": "./ets/specifiedability/SpecifiedAbility.ets",
"description": "$string:SpecifiedAbility_desc",
"icon": "$media:layered_image",
"launchType": "specified", // 重点这里
"label": "$string:SpecifiedAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background"
}
],
...
默认工程指定入口窗口EntryUIAbility
使用的是pages/Index.etx的启动页面,我们在这个页面增加几个按钮实现跳转,这样准备工作基本完成。
@Entry
@Component
struct Index {
build() {
Column() {
Button("打开单实例窗口")
.onClick(() => {
let context = getContext(this) as common.UIAbilityContext
let want: Want = {
bundleName: 'com.byrain.example_001',
abilityName: 'SingletonAbility'
};
context.startAbility(want);
})
Button("打开多实例窗口")
.onClick(() => {
let context = getContext(this) as common.UIAbilityContext
let want: Want = {
bundleName: 'com.byrain.example_001',
abilityName: 'MultitonAbility'
};
context.startAbility(want);
})
... // 指定启动模式下面单独说
}
.height('100%')
.width('100%')
}
}
几个UIAbility使用的page都是Index.ets
,所以界面都是一样的,现在启动应用,
单实例验证
点击打开单实例,会打开新页面,在新页面再次点击打开单实例界面没有反应。我们看日志
02-21 16:07:08.592 13468-13468 A00000/testTag pid-13468 I EntryAbility onCreate
02-21 16:07:08.644 13468-13468 A00000/testTag pid-13468 I EntryAbility onWindowStageCreate
02-21 16:07:08.654 13468-13468 A00000/testTag pid-13468 I EntryAbility onForeground
02-21 16:07:08.710 13468-13468 A00000/testTag pid-13468 I Succeeded in loading the content.
02-21 16:08:08.640 13468-13468 A00000/testTag com.byrai...mple_001 I EntryAbility onBackground
02-21 16:08:08.688 13468-13468 A00000/testTag com.byrai...mple_001 I SingletonAbility onCreate
02-21 16:08:08.717 13468-13468 A00000/testTag com.byrai...mple_001 I SingletonAbility onWindowStageCreate
02-21 16:08:08.730 13468-13468 A00000/testTag com.byrai...mple_001 I SingletonAbility onForeground
02-21 16:08:08.768 13468-13468 A00000/testTag com.byrai...mple_001 I Succeeded in loading the content.
02-21 16:08:10.499 13468-13468 A00000/testTag com.byrai...mple_001 I SingletonAbility onNewWant
02-21 16:08:11.722 13468-13468 A00000/testTag com.byrai...mple_001 I SingletonAbility onNewWant
第一次打开单例窗口后,UIAbility创建新实例,再次单击打开时候则进入onNewWant()
回调,当前窗口仅创建一个。
我们通过aa工具查看也确实仅有两个UIAbility
$ aa dump -l
User ID #100
current mission lists:{
Mission ID #136 mission name #[#com.byrain.example_001:entry:EntryAbility] lockedState #0 mission affinity #[]
AbilityRecord ID #1725
app name [com.byrain.example_001]
main name [EntryAbility]
bundle name [com.byrain.example_001]
ability type [PAGE]
state #BACKGROUND start time [98914947]
app state #FOREGROUND
ready #1 window attached #0 launcher #0
callee connections:
isKeepAlive: false
}
Mission ID #137 mission name #[#com.byrain.example_001:entry:SingletonAbility] lockedState #0 mission affinity #[]
AbilityRecord ID #1727
app name [com.byrain.example_001]
main name [SingletonAbility]
bundle name [com.byrain.example_001]
ability type [PAGE]
state #FOREGROUND start time [98975152]
app state #FOREGROUND
ready #1 window attached #0 launcher #0
callee connections:
isKeepAlive: false
}
多实例验证
我们结束进程,然后从新打开应用,点击打开多实例此时会打开新页面,在新页面点击打开多实例会再次打开个新页面。我们看日志执行
02-21 16:20:32.147 16786-16786 A00000/testTag com.byrai...mple_001 I EntryAbility onCreate
02-21 16:20:32.170 16786-16786 A00000/testTag com.byrai...mple_001 I EntryAbility onWindowStageCreate
02-21 16:20:32.179 16786-16786 A00000/testTag com.byrai...mple_001 I EntryAbility onForeground
02-21 16:20:32.217 16786-16786 A00000/testTag com.byrai...mple_001 I Succeeded in loading the content.
02-21 16:20:34.117 16786-16786 A00000/testTag com.byrai...mple_001 I EntryAbility onBackground
02-21 16:20:34.126 16786-16786 A00000/testTag com.byrai...mple_001 I MultitonAbility onCreate
02-21 16:20:34.147 16786-16786 A00000/testTag com.byrai...mple_001 I MultitonAbility onWindowStageCreate
02-21 16:20:34.153 16786-16786 A00000/testTag com.byrai...mple_001 I MultitonAbility onForeground
02-21 16:20:34.188 16786-16786 A00000/testTag com.byrai...mple_001 I Succeeded in loading the content.
02-21 16:20:36.328 16786-16786 A00000/testTag com.byrai...mple_001 I MultitonAbility onBackground
02-21 16:20:36.332 16786-16786 A00000/testTag com.byrai...mple_001 I MultitonAbility onCreate
02-21 16:20:36.339 16786-16786 A00000/testTag com.byrai...mple_001 I MultitonAbility onWindowStageCreate
02-21 16:20:36.345 16786-16786 A00000/testTag com.byrai...mple_001 I MultitonAbility onForeground
02-21 16:20:36.374 16786-16786 A00000/testTag com.byrai...mple_001 I Succeeded in loading the content.
02-21 16:20:38.631 16786-16786 A00000/testTag com.byrai...mple_001 I MultitonAbility onCreate
02-21 16:20:38.647 16786-16786 A00000/testTag com.byrai...mple_001 I MultitonAbility onWindowStageCreate
02-21 16:20:38.663 16786-16786 A00000/testTag com.byrai...mple_001 I MultitonAbility onForeground
02-21 16:20:38.663 16786-16786 A00000/testTag com.byrai...mple_001 I MultitonAbility onBackground
02-21 16:20:38.684 16786-16786 A00000/testTag com.byrai...mple_001 I Succeeded in loading the content.
每次打开都会创建一个新的UIAbility实例,通过aa
工具也可以看到有4个UIAbility。
$ aa dump -l
User ID #100
current mission lists:{
Mission ID #138 mission name #[#com.byrain.example_001:entry:EntryAbility] lockedState #0 mission affinity #[]
AbilityRecord ID #1740
app name [com.byrain.example_001]
main name [EntryAbility]
bundle name [com.byrain.example_001]
ability type [PAGE]
state #BACKGROUND start time [99718497]
app state #FOREGROUND
ready #1 window attached #0 launcher #0
callee connections:
isKeepAlive: false
}
Mission ID #139 mission name #[#com.byrain.example_001:entry:MultitonAbility] lockedState #0 mission affinity #[]
AbilityRecord ID #1741
app name [com.byrain.example_001]
main name [MultitonAbility]
bundle name [com.byrain.example_001]
ability type [PAGE]
state #BACKGROUND start time [99720633]
app state #FOREGROUND
ready #1 window attached #0 launcher #0
callee connections:
isKeepAlive: false
}
Mission ID #140 mission name #[#com.byrain.example_001:entry:MultitonAbility] lockedState #0 mission affinity #[]
AbilityRecord ID #1742
app name [com.byrain.example_001]
main name [MultitonAbility]
bundle name [com.byrain.example_001]
ability type [PAGE]
state #BACKGROUND start time [99722839]
app state #FOREGROUND
ready #1 window attached #0 launcher #0
callee connections:
isKeepAlive: false
}
Mission ID #141 mission name #[#com.byrain.example_001:entry:MultitonAbility] lockedState #0 mission affinity #[]
AbilityRecord ID #1743
app name [com.byrain.example_001]
main name [MultitonAbility]
bundle name [com.byrain.example_001]
ability type [PAGE]
state #FOREGROUND start time [99725149]
app state #FOREGROUND
ready #1 window attached #0 launcher #0
callee connections:
isKeepAlive: false
}
指定启动模式验证
指定启动模式是自定义页面启动模式,所以不是简单配置后直接调用startAbility
,这里需要介绍下AbilityStage
。
AbilityStage
类似Android里的Application,AbilityStage
是HarmonyOS中Stage模型
的一个核心组件,用于管理应用的生命周期和状态。这里我们主要使用AbilityStage
的onAcceptWant
的生命周期回调,判断指定启动模式的UIAbility是否是单实例主要在这个回调中处理。
我们在Index.etx
中增加启动指定启动模式的按钮,在启动时候传入的Want
(下一篇介绍)并在其属性parameters
中指定参数
Button("打开指定模式为单实例窗口")
.onClick(() => {
let context = getContext(this) as common.UIAbilityContext
let want: Want = {
bundleName: 'com.byrain.example_001',
abilityName: 'SpecifiedAbility',
parameters: {
type: 1
}
};
context.startAbility(want);
})
Button("打开指定模式为多实例窗口")
.onClick(() => {
let context = getContext(this) as common.UIAbilityContext
let num = LocalStorage.getShared().get("type") as number
if (num == undefined) {
num = 1;
}
num = num + 1;
hilog.info(0x0000, 'testTag', '%{public}s', `启动页面类型值${num}`);
let want: Want = {
bundleName: 'com.byrain.example_001',
abilityName: 'SpecifiedAbility',
parameters: {
type: num
}
};
context.startAbility(want);
})
然后我们自定义AbilityStage,实现onAcceptWant
回调,在这里根据want参数返回字符串
export default class Example_001AbilityStage extends AbilityStage {
onAcceptWant(want: Want): string {
// 这里的want可以接收startAbility时候传入的want参数
if (want.abilityName === 'SpecifiedAbility' && want.parameters) {
// 如果跳转的UIAbility是指定启动模式的UIAbility则根据参数type返回不同的字符串,
// 如果每次返回相同的字符串,则代表启动的是单实例UIAbility。这里返回的字符串是UIAbility的唯一标识
if (want.parameters.type) {
hilog.info(0x0000, 'testTag', '%{public}s', `接收到的指定启动模式的参数值${want.parameters.type}`);
return `SpecifiedAbility${want.parameters.type}`
}
}
return super.onAcceptWant(want)
}
}
我们重新启动应用,点击打开指定模式为单实例窗口,在打开的新页面再次点击,看日志:
02-21 16:42:27.312 21526-21526 A00000/testTag com.byrai...mple_001 I EntryAbility onCreate
02-21 16:42:27.324 21526-21526 A00000/testTag com.byrai...mple_001 I EntryAbility onWindowStageCreate
02-21 16:42:27.332 21526-21526 A00000/testTag com.byrai...mple_001 I EntryAbility onForeground
02-21 16:42:27.371 21526-21526 A00000/testTag com.byrai...mple_001 I Succeeded in loading the content.
02-21 16:42:29.036 21526-21526 A00000/testTag com.byrai...mple_001 I 接收到的指定启动模式的参数值1
02-21 16:42:29.063 21526-21526 A00000/testTag com.byrai...mple_001 I EntryAbility onBackground
02-21 16:42:29.071 21526-21526 A00000/testTag com.byrai...mple_001 I SpecifiedAbility onCreate
02-21 16:42:29.076 21526-21526 A00000/testTag com.byrai...mple_001 I specifiedability onWindowStageCreate
02-21 16:42:29.079 21526-21526 A00000/testTag com.byrai...mple_001 I SpecifiedAbility onForeground
02-21 16:42:29.098 21526-21526 A00000/testTag com.byrai...mple_001 I Succeeded in loading the content.
02-21 16:42:30.027 21526-21526 A00000/testTag com.byrai...mple_001 I 接收到的指定启动模式的参数值1
02-21 16:42:30.032 21526-21526 A00000/testTag com.byrai...mple_001 I SpecifiedAbility onNewWant
02-21 16:42:30.693 21526-21526 A00000/testTag com.byrai...mple_001 I 接收到的指定启动模式的参数值1
02-21 16:42:30.701 21526-21526 A00000/testTag com.byrai...mple_001 I SpecifiedAbility onNewWant
可以看到后面再次启动时候则走的SpecifiedAbility回调onNewWant
,通过aa
工具查看,只有2个UIAbility
$ aa dump -l
User ID #100
current mission lists:{
Mission ID #142 mission name #[#com.byrain.example_001:entry:EntryAbility] lockedState #0 mission affinity #[]
AbilityRecord ID #1765
app name [com.byrain.example_001]
main name [EntryAbility]
bundle name [com.byrain.example_001]
ability type [PAGE]
state #BACKGROUND start time [101033688]
app state #FOREGROUND
ready #1 window attached #0 launcher #0
callee connections:
isKeepAlive: false
}
Mission ID #143 mission name #[#com.byrain.example_001:entry:SpecifiedAbility] lockedState #0 mission affinity #[]
AbilityRecord ID #1766
app name [com.byrain.example_001]
main name [SpecifiedAbility]
bundle name [com.byrain.example_001]
ability type [PAGE]
state #FOREGROUND start time [101035574]
app state #FOREGROUND
ready #1 window attached #0 launcher #0
callee connections:
isKeepAlive: false
}
我们再次重新启动应用,点击打开指定模式为多实例窗口,在打开的新页面再次点击,看日志:
02-21 16:52:12.299 23949-23949 A00000/testTag pid-23949 I EntryAbility onCreate
02-21 16:52:12.314 23949-23949 A00000/testTag com.byrai...mple_001 I EntryAbility onWindowStageCreate
02-21 16:52:12.329 23949-23949 A00000/testTag com.byrai...mple_001 I EntryAbility onForeground
02-21 16:52:12.374 23949-23949 A00000/testTag com.byrai...mple_001 I Succeeded in loading the content.
02-21 16:52:14.130 23949-23949 A00000/testTag com.byrai...mple_001 I 启动页面类型值2
02-21 16:52:14.136 23949-23949 A00000/testTag com.byrai...mple_001 I 接收到的指定启动模式的参数值2
02-21 16:52:14.161 23949-23949 A00000/testTag com.byrai...mple_001 I EntryAbility onBackground
02-21 16:52:14.167 23949-23949 A00000/testTag com.byrai...mple_001 I SpecifiedAbility onCreate
02-21 16:52:14.179 23949-23949 A00000/testTag com.byrai...mple_001 I specifiedability onWindowStageCreate
02-21 16:52:14.182 23949-23949 A00000/testTag com.byrai...mple_001 I SpecifiedAbility onForeground
02-21 16:52:14.199 23949-23949 A00000/testTag com.byrai...mple_001 I Succeeded in loading the content.
02-21 16:52:15.209 23949-23949 A00000/testTag com.byrai...mple_001 I 启动页面类型值3
02-21 16:52:15.213 23949-23949 A00000/testTag com.byrai...mple_001 I 接收到的指定启动模式的参数值3
02-21 16:52:15.234 23949-23949 A00000/testTag com.byrai...mple_001 I SpecifiedAbility onBackground
02-21 16:52:15.247 23949-23949 A00000/testTag com.byrai...mple_001 I SpecifiedAbility onCreate
02-21 16:52:15.254 23949-23949 A00000/testTag com.byrai...mple_001 I specifiedability onWindowStageCreate
02-21 16:52:15.256 23949-23949 A00000/testTag com.byrai...mple_001 I SpecifiedAbility onForeground
02-21 16:52:15.293 23949-23949 A00000/testTag com.byrai...mple_001 I Succeeded in loading the content.
同样启动SpecifiedAbility,这时每次点击都会创建一个新实例,aa
查看有3个UIAbility实例
$ aa dump -l
User ID #100
current mission lists:{
Mission ID #144 mission name #[#com.byrain.example_001:entry:EntryAbility] lockedState #0 mission affinity #[]
AbilityRecord ID #1777
app name [com.byrain.example_001]
main name [EntryAbility]
bundle name [com.byrain.example_001]
ability type [PAGE]
state #BACKGROUND start time [101618688]
app state #FOREGROUND
ready #1 window attached #0 launcher #0
callee connections:
isKeepAlive: false
}
Mission ID #145 mission name #[#com.byrain.example_001:entry:SpecifiedAbility] lockedState #0 mission affinity #[]
AbilityRecord ID #1778
app name [com.byrain.example_001]
main name [SpecifiedAbility]
bundle name [com.byrain.example_001]
ability type [PAGE]
state #BACKGROUND start time [101620679]
app state #FOREGROUND
ready #1 window attached #0 launcher #0
callee connections:
isKeepAlive: false
}
Mission ID #146 mission name #[#com.byrain.example_001:entry:SpecifiedAbility] lockedState #0 mission affinity #[]
AbilityRecord ID #1779
app name [com.byrain.example_001]
main name [SpecifiedAbility]
bundle name [com.byrain.example_001]
ability type [PAGE]
state #FOREGROUND start time [101621751]
app state #FOREGROUND
ready #1 window attached #0 launcher #0
callee connections:
isKeepAlive: false
}
以上就是UIAbility启动模式介绍,欢迎点赞、关注+收藏