在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中棧的狀態。
圖1
現在假設Page Ability1的launchType屬性值是standard,那麼從Page Ability1中啟動Page Ability1,如果啟動2次,就會再建立兩個Page Ability1例項,這時棧的狀態如圖2所示。
圖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所示。
圖3
在LaunchTypeAbility類中有一個靜態變數count,如果每次顯示LaunchTypeAbility時都建立一個新的例項,那麼count會不斷加1,例如,如果顯示3次LaunchTypeAbility,應該看到如圖4所示的視窗。
圖4
如果將LaunchTypeAbility的launchType屬性值改成singleton,那麼不管顯示多少次LaunchTypeAbility,計數器count的值永遠是1,如圖5所示。因為LaunchTypeAbility在建立一個例項後,就不會再建立新的LaunchTypeAbility例項了,所以onStart方法自然就不會再次呼叫了。
圖5