UIAbility組件啟動(dòng)模式
UIAbility的啟動(dòng)模式是指UIAbility實(shí)例在啟動(dòng)時(shí)的不同呈現(xiàn)狀態(tài)。針對(duì)不同的業(yè)務(wù)場(chǎng)景,系統(tǒng)提供了三種啟動(dòng)模式:
singleton啟動(dòng)模式
singleton啟動(dòng)模式為單實(shí)例模式,也是默認(rèn)情況下的啟動(dòng)模式。
每次調(diào)用[startAbility()
]方法時(shí),如果應(yīng)用進(jìn)程中該類型的UIAbility實(shí)例已經(jīng)存在,則復(fù)用系統(tǒng)中的UIAbility實(shí)例。系統(tǒng)中只存在唯一一個(gè)該UIAbility實(shí)例,即在最近任務(wù)列表中只存在一個(gè)該類型的UIAbility實(shí)例。
圖1 單實(shí)例模式演示效果
說明 :
開發(fā)前請(qǐng)熟悉鴻蒙開發(fā)指導(dǎo)文檔 :[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
]
應(yīng)用的UIAbility實(shí)例已創(chuàng)建,該UIAbility配置為單實(shí)例模式,再次調(diào)用[startAbility()
]方法啟動(dòng)該UIAbility實(shí)例。由于啟動(dòng)的還是原來的UIAbility實(shí)例,并未重新創(chuàng)建一個(gè)新的UIAbility實(shí)例,此時(shí)只會(huì)進(jìn)入該UIAbility的[onNewWant()
]回調(diào),不會(huì)進(jìn)入其[onCreate()
]和[onWindowStageCreate()
]生命周期回調(diào)。
如果需要使用singleton啟動(dòng)模式,在[module.json5配置文件]中的launchType
字段配置為singleton
即可。
{
"module": {
...
"abilities": [
{
"launchType": "singleton",
...
}
]
}
}
multiton啟動(dòng)模式
multiton啟動(dòng)模式為多實(shí)例模式,每次調(diào)用[startAbility()
]方法時(shí),都會(huì)在應(yīng)用進(jìn)程中創(chuàng)建一個(gè)新的該類型UIAbility實(shí)例。即在最近任務(wù)列表中可以看到有多個(gè)該類型的UIAbility實(shí)例。這種情況下可以將UIAbility配置為multiton(多實(shí)例模式)。
圖2 多實(shí)例模式演示效果
multiton啟動(dòng)模式的開發(fā)使用,在[module.json5配置文件]中的launchType
字段配置為multiton
即可。
{
"module": {
...
"abilities": [
{
"launchType": "multiton",
...
}
]
}
}
specified啟動(dòng)模式
specified啟動(dòng)模式為指定實(shí)例模式,針對(duì)一些特殊場(chǎng)景使用(例如文檔應(yīng)用中每次新建文檔希望都能新建一個(gè)文檔實(shí)例,重復(fù)打開一個(gè)已保存的文檔希望打開的都是同一個(gè)文檔實(shí)例)。
圖3 指定實(shí)例模式演示效果
例如有兩個(gè)UIAbility:EntryAbility和SpecifiedAbility,SpecifiedAbility配置為指定實(shí)例模式啟動(dòng),需要從EntryAbility的頁(yè)面中啟動(dòng)SpecifiedAbility。
- 在SpecifiedAbility中,將[module.json5配置文件]的
launchType
字段配置為specified
。{ "module": { ... "abilities": [ { "launchType": "specified", ... } ] } }
- 在創(chuàng)建UIAbility實(shí)例之前,開發(fā)者可以為該實(shí)例指定一個(gè)唯一的字符串Key,這樣在調(diào)用[
startAbility()
]方法時(shí),應(yīng)用就可以根據(jù)指定的Key來識(shí)別響應(yīng)請(qǐng)求的UIAbility實(shí)例。在EntryAbility中,調(diào)用[startAbility()
]方法時(shí),可以在want
參數(shù)中增加一個(gè)自定義參數(shù),例如instanceKey
,以此來區(qū)分不同的UIAbility實(shí)例。// 在啟動(dòng)指定實(shí)例模式的UIAbility時(shí),給每一個(gè)UIAbility實(shí)例配置一個(gè)獨(dú)立的Key標(biāo)識(shí) // 例如在文檔使用場(chǎng)景中,可以用文檔路徑作為Key標(biāo)識(shí) import common from '@ohos.app.ability.common'; import hilog from '@ohos.hilog'; import Want from '@ohos.app.ability.Want'; import { BusinessError } from '@ohos.base'; const TAG: string = '[Page_StartModel]'; const DOMAIN_NUMBER: number = 0xFF00; function getInstance() : string { return 'KEY'; } @Entry @Component struct Page_StartModel { private KEY_NEW = 'KEY'; build() { Row() { Column() { // ... Button() // ... .onClick(() = > { let context:common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // context為調(diào)用方UIAbility的UIAbilityContext; let want: Want = { deviceId: '', // deviceId為空表示本設(shè)備 bundleName: 'com.samples.stagemodelabilitydevelop', abilityName: 'SpecifiedFirstAbility', moduleName: 'entry', // moduleName非必選 parameters: { // 自定義信息 instanceKey: this.KEY_NEW } }; context.startAbility(want).then(() = > { hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in starting SpecifiedAbility.'); }).catch((err: BusinessError) = > { hilog.error(DOMAIN_NUMBER, TAG, `Failed to start SpecifiedAbility. Code is ${err.code}, message is ${err.message}`); }) this.KEY_NEW = this.KEY_NEW + 'a'; }) // ... Button() // ... .onClick(() = > { let context:common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // context為調(diào)用方UIAbility的UIAbilityContext; let want: Want = { deviceId: '', // deviceId為空表示本設(shè)備 bundleName: 'com.samples.stagemodelabilitydevelop', abilityName: 'SpecifiedSecondAbility', moduleName: 'entry', // moduleName非必選 parameters: { // 自定義信息 instanceKey: getInstance() } }; context.startAbility(want).then(() = > { hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in starting SpecifiedAbility.'); }).catch((err: BusinessError) = > { hilog.error(DOMAIN_NUMBER, TAG, `Failed to start SpecifiedAbility. Code is ${err.code}, message is ${err.message}`); }) this.KEY_NEW = this.KEY_NEW + 'a'; }) // ... } .width('100%') } .height('100%') } }
- 由于SpecifiedAbility的啟動(dòng)模式被配置為指定實(shí)例啟動(dòng)模式,因此在SpecifiedAbility啟動(dòng)之前,會(huì)先進(jìn)入對(duì)應(yīng)的AbilityStage的[
onAcceptWant()
]生命周期回調(diào)中,以獲取該UIAbility實(shí)例的Key值。然后系統(tǒng)會(huì)自動(dòng)匹配,如果存在與該UIAbility實(shí)例匹配的Key,則會(huì)啟動(dòng)與之綁定的UIAbility實(shí)例,并進(jìn)入該UIAbility實(shí)例的[onNewWant()
]回調(diào)函數(shù);否則會(huì)創(chuàng)建一個(gè)新的UIAbility實(shí)例,并進(jìn)入該UIAbility實(shí)例的[onCreate()
]回調(diào)函數(shù)和[onWindowStageCreate()
]回調(diào)函數(shù)。
示例代碼中,通過實(shí)現(xiàn)[onAcceptWant()
]生命周期回調(diào)函數(shù),解析傳入的want
參數(shù),獲取自定義參數(shù)instanceKey
。業(yè)務(wù)邏輯會(huì)根據(jù)這個(gè)參數(shù)返回一個(gè)字符串Key,用于標(biāo)識(shí)當(dāng)前UIAbility實(shí)例。如果返回的Key已經(jīng)對(duì)應(yīng)一個(gè)已啟動(dòng)的UIAbility實(shí)例,系統(tǒng)會(huì)將該UIAbility實(shí)例拉回前臺(tái)并獲焦,而不會(huì)創(chuàng)建新的實(shí)例。如果返回的Key沒有對(duì)應(yīng)已啟動(dòng)的UIAbility實(shí)例,則系統(tǒng)會(huì)創(chuàng)建新的UIAbility實(shí)例并啟動(dòng)。import AbilityStage from '@ohos.app.ability.AbilityStage'; import type Want from '@ohos.app.ability.Want'; export default class MyAbilityStage extends AbilityStage { onAcceptWant(want: Want): string { // 在被調(diào)用方的AbilityStage中,針對(duì)啟動(dòng)模式為specified的UIAbility返回一個(gè)UIAbility實(shí)例對(duì)應(yīng)的一個(gè)Key值 // 當(dāng)前示例指的是module1 Module的SpecifiedAbility if (want.abilityName === 'SpecifiedFirstAbility' || want.abilityName === 'SpecifiedSecondAbility') { // 返回的字符串Key標(biāo)識(shí)為自定義拼接的字符串內(nèi)容 if (want.parameters) { return `SpecifiedAbilityInstance_${want.parameters.instanceKey}`; } } // ... return 'MyAbilityStage'; } }
說明:
HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿
- 當(dāng)應(yīng)用的UIAbility實(shí)例已經(jīng)被創(chuàng)建,并且配置為指定實(shí)例模式時(shí),如果再次調(diào)用[
startAbility()
]方法啟動(dòng)該UIAbility實(shí)例,且[AbilityStage]的[onAcceptWant()
]回調(diào)匹配到一個(gè)已創(chuàng)建的UIAbility實(shí)例,則系統(tǒng)會(huì)啟動(dòng)原來的UIAbility實(shí)例,并且不會(huì)重新創(chuàng)建一個(gè)新的UIAbility實(shí)例。此時(shí),該UIAbility實(shí)例的[onNewWant()
]回調(diào)會(huì)被觸發(fā),而不會(huì)觸發(fā)[onCreate()
]和[onWindowStageCreate()
]生命周期回調(diào)。- DevEco Studio默認(rèn)工程中未自動(dòng)生成AbilityStage,AbilityStage文件的創(chuàng)建請(qǐng)參見[AbilityStage組件容器]。
例如在文檔應(yīng)用中,可以為不同的文檔實(shí)例內(nèi)容綁定不同的Key值。每次新建文檔時(shí),可以傳入一個(gè)新的Key值(例如可以將文件的路徑作為一個(gè)Key標(biāo)識(shí)),此時(shí)AbilityStage中啟動(dòng)UIAbility時(shí)都會(huì)創(chuàng)建一個(gè)新的UIAbility實(shí)例;當(dāng)新建的文檔保存之后,回到桌面,或者新打開一個(gè)已保存的文檔,回到桌面,此時(shí)再次打開該已保存的文檔,此時(shí)AbilityStage中再次啟動(dòng)該UIAbility時(shí),打開的仍然是之前原來已保存的文檔界面。
以如下步驟所示進(jìn)行舉例說明。
1. 打開`文件A`,對(duì)應(yīng)啟動(dòng)一個(gè)新的UIAbility實(shí)例,例如啟動(dòng)`UIAbility實(shí)例1`。
1. 在最近任務(wù)列表中關(guān)閉`文件A`的任務(wù)進(jìn)程,此時(shí)`UIAbility實(shí)例1`被銷毀,回到桌面,再次打開`文件A`,此時(shí)對(duì)應(yīng)啟動(dòng)一個(gè)新的UIAbility實(shí)例,例如啟動(dòng)`UIAbility實(shí)例2`。
1. 回到桌面,打開`文件B`,此時(shí)對(duì)應(yīng)啟動(dòng)一個(gè)新的UIAbility實(shí)例,例如啟動(dòng)`UIAbility實(shí)例3`。
1. 回到桌面,再次打開`文件A`,此時(shí)仍然啟動(dòng)之前的`UIAbility實(shí)例2`,因?yàn)橄到y(tǒng)會(huì)自動(dòng)匹配UIAbility實(shí)例的Key值,如果存在與之匹配的Key,則會(huì)啟動(dòng)與之綁定的UIAbility實(shí)例。在此例中,之前啟動(dòng)的`UIAbility實(shí)例2`與`文件A`綁定的Key是相同的,因此系統(tǒng)會(huì)拉回`UIAbility實(shí)例2`并讓其獲焦,而不會(huì)創(chuàng)建新的實(shí)例。
審核編輯 黃宇
-
框架
+關(guān)注
關(guān)注
0文章
398瀏覽量
17404 -
組件
+關(guān)注
關(guān)注
1文章
503瀏覽量
17786 -
鴻蒙
+關(guān)注
關(guān)注
57文章
2302瀏覽量
42689
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論