https://harmonyos.51cto.com/#zz
在Page Ability的配置信息(config.json文件)中有一个launchType属性,通过模板默认生成的值是standard,这是launchType属性的默认值(可以不设置launchType,这样默认值就是standard)。launchType属性的另外一个可以设置的值是singleton。这两个属性值的区别如下:
standard:在任何情况下,无论Page Ability被显示多少次,都会创建一个新的Page Ability实例;
singleton:如果要显示的Page Ability在栈顶,那么再次显示这个Page Ability时,不会再创建新的Page Ability实例,而是直接使用这个Page Ability实例。如果Page Ability上面有其他的Page Ability,那么首先弹出这些Page Ability,然后再重用这个Page Ability。总之,拥有singleton模式的Page Ability将永远使用唯一的实例;
这里涉及到一个栈的概念,这是HarmonyOS管理Page Ability的模式。HarmonyOS App同时只能显示一个Page Ability,那么哪一个Page Ability才能显示呢?HarmonyOS App会使用一个栈来管理App中所有的Page Ability,只有在栈顶的Page Ability才会显示。如果要想让栈中第2个Page Ability显示,那么栈顶的Page Ability就必须出栈,也就是销毁Page Ability,也就是调用terminateAbility方法要完成的工作。
下面用图示来说明这一过程。图1中每一个矩形区域表示App中当前用于保存Page Ability的栈。1中只有一个Page Ability1,如果让Page Ability2显示,那么Page Ability2必须压栈,Page Ability3显示也需要完成同样的工作。在3的状态中,如果让Page Ability2显示,那么Page Ability3必须出栈,就形成了4中栈的状态。

现在假设Page Ability1的launchType属性值是standard,那么从Page Ability1中启动Page Ability1,如果启动2次,就会再创建两个Page Ability1实例,这时栈的状态如图2所示。

很明显,在栈中有3个Page Ability1实例。
如果Page Ability1的launchType属性值是singleton,那么不管显示多少次Page Ability1,在栈中永远只有1个Page Ability1实例。所以如果想让某一个Page Ability1永远只有一个实例的时候,可以将该Page Ability的launchType属性值设为singleton。
下面通过一个案例来演示standard和singleton的区别。
首先创建一个名为LaunchTypeAbility的Page Ability,并编写下面的代码:
- package com.unitymarvel.demo.ability;
- import com.unitymarvel.demo.ResourceTable;
- import ohos.aafwk.ability.Ability;
- import ohos.aafwk.content.Intent;
- import ohos.agp.components.Button;
- import ohos.agp.components.Component;
- import ohos.agp.components.Text;
- public class LaunchTypeAbility extends Ability {
- private static int count = 0; // 计数器
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setUIContent(ResourceTable.Layout_launch_type_layout);
- count++;
- Text text = (Text)findComponentById(ResourceTable.Id_text);
- if(text != null) {
- text.setText(String.valueOf(count));
- }
- Button buttonStartAbility = (Button)findComponentById(ResourceTable.Id_button_start_ability);
- if(buttonStartAbility != null) {
- buttonStartAbility.setClickedListener(new Component.ClickedListener() {
- @Override
- public void onClick(Component component) {
- Intent intent = new Intent();
- intent.setAction("action.harmonyos.demo.ability.testlaunchtype");
- // 显示另外一个Page Ability
- startAbility(intent);
- }
- });
- }
- }
- }
在config.json文件中配置LaunchTypeAbility,代码如下:
- {
- "skills": [
- {
- "actions": [
- "action.harmonyos.demo.ability.launchtype"
- ]
- }
- ],
- "orientation": "landscape",
- "formEnabled": false,
- "name": "com.unitymarvel.demo.ability.LaunchTypeAbility",
- "icon": "$media:icon",
- "label": "Page Ability的启动类型",
- "type": "page",
- "launchType": "standard"
- }
这里将LaunchTypeAbility的launchType属性值设为standard。
然后再创建另外一个名为TestLaunchTypeAbility的Page Ability,代码如下:
- package com.unitymarvel.demo.ability;
- import com.unitymarvel.demo.ResourceTable;
- import ohos.aafwk.ability.Ability;
- import ohos.aafwk.content.Intent;
- import ohos.agp.components.Button;
- import ohos.agp.components.Component;
- import ohos.agp.components.Text;
- public class TestLaunchTypeAbility extends Ability {
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setUIContent(ResourceTable.Layout_launch_type_layout);
- Button buttonStartAbility =
- (Button)findComponentById(ResourceTable.Id_button_start_ability);
- if(buttonStartAbility != null) {
- buttonStartAbility.setClickedListener(new Component.ClickedListener() {
- @Override
- public void onClick(Component component) {
- Intent intent = new Intent();
- intent.setAction("action.harmonyos.demo.ability.launchtype");
- // 显示LaunchTypeAbility
- startAbility(intent);
- }
- });
- }
- }
- }
本例包含两个Page Ability:LaunchTypeAbility和TestLaunchTypeAbility。目前这两个Page Ability的launchType属性值都是standard。这两个Page Ability的关系是LaunchTypeAbility显示TestLaunchTypeAbility,然后TestLaunchTypeAbility再显示LaunchTypeAbility,如图3所示。

在LaunchTypeAbility类中有一个静态变量count,如果每次显示LaunchTypeAbility时都创建一个新的实例,那么count会不断加1,例如,如果显示3次LaunchTypeAbility,应该看到如图4所示的窗口。

如果将LaunchTypeAbility的launchType属性值改成singleton,那么不管显示多少次LaunchTypeAbility,计数器count的值永远是1,如图5所示。因为LaunchTypeAbility在创建一个实例后,就不会再创建新的LaunchTypeAbility实例了,所以onStart方法自然就不会再次调用了。

欢迎访问李宁老师的【鸿蒙基地】专栏:https://harmonyos.51cto.com/column/17
李宁老师的课程主页:https://edu.51cto.com/lecturer/974126.html
https://harmonyos.51cto.com/#zz
【编辑推荐】