在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 Ability的启动类型(LaunchType)-LMLPHP

              图1

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

图解鸿蒙Page Ability的启动类型(LaunchType)-LMLPHP

         图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所示。

图解鸿蒙Page Ability的启动类型(LaunchType)-LMLPHP

               图3

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

图解鸿蒙Page Ability的启动类型(LaunchType)-LMLPHP

                                                           图4

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

图解鸿蒙Page Ability的启动类型(LaunchType)-LMLPHP

                图5

- EOF -

推荐阅读  点击标题可跳转

鸿蒙IDE(DevEco Studio)怎样1秒下载Gradle

特大喜讯!鸿蒙项目来了:在线电子词典

【喜讯、喜讯】期待已久的鸿蒙IDE macOS版终于发布了!

【直播回放】独家传授:成为Python高手的武功秘籍

调试鸿蒙(HarmonyOS)App源代码的两种方式

开发跨设备的鸿蒙(HarmonyOS) App

鸿蒙(HarmonyOS)大神都喜欢玩命令行

关注「极客起源」公众号,加星标,不错过精彩技术干货

03-26 16:14