打开多个互不干扰的独立窗口,可以通过startAbility打开多个UIAbility实例实现,每个UIAbility实例通过WindowStage持有一个主窗口,各个主窗口可以实现独立的功能。参考示例如下:
import { common, Want } from '@kit.AbilityKit'; @Entry @Component struct DocumentListPage { private index: number = 1; @State docs: number[] = []; private context = this.getUIContext().getHostContext() as common.UIAbilityContext; build() { Row() { Column({ space: 10 }) { Button('新建文档') .onClick(() => { // 添加文档 this.docs.push(this.index); // 跳转的目的地want,参数须根据实际情况替换 let want: Want = { deviceId: '', bundleName: 'com.example.myapplication', moduleName: 'entry', abilityName: 'DocumentAbility', parameters: { instanceKey: 'idx_' + this.index++ } }; // 跳转 this.context.startAbility(want); }); ForEach(this.docs, (idx: number) => { Row({ space: 10 }) { Image('') .width(20) .aspectRatio(1) .backgroundColor(Color.Blue); Text(`文档${idx}`) .fontSize(18) .onClick(() => { // 跳转的目的地want,参数须根据实际情况替换 let want: Want = { deviceId: '', bundleName: 'com.example.myapplication', moduleName: 'entry', abilityName: 'DocumentAbility', parameters: { instanceKey: 'idx_' + idx } }; // 跳转 this.context.startAbility(want); }); }.width('100%'); }); } .width('100%') .height('100%') .padding(20); }; } }
import { UIAbility } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; export default class DocumentAbility extends UIAbility { onCreate(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); } onDestroy(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); } onWindowStageCreate(windowStage: window.WindowStage): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); windowStage.loadContent('pages/DocumentPage', (err) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); }); } onWindowStageDestroy(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); } onForeground(): void { // Ability has brought to foreground hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); } onBackground(): void { // Ability has back to background hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); } };
import { common, Want } from '@kit.AbilityKit'; @Entry @Component struct DocumentPage { private context = this.getUIContext().getHostContext() as common.UIAbilityContext; @State content: string = ''; build() { Row() { Column({ space: 10 }) { Row({ space: 10 }) { SymbolGlyph($r('sys.symbol.arrow_left_circle')) .fontSize(50) .onClick(() => { // 跳转的目的地want,参数须根据实际情况替换 let want: Want = { deviceId: '', bundleName: 'com.example.myapplication', moduleName: 'entry', abilityName: 'EntryAbility', }; // 跳转 this.context.startAbility(want); }); Text('这里是标题,点前面符号跳转') .fontSize(30) .fontWeight(FontWeight.Bold); } .width('100%'); Divider(); TextArea({ placeholder: '请输入文档内容', text: this.content }) .layoutWeight(1) .onChange(val => this.content = val); } .width('100%') .height('100%') .padding(10); }; } }
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:layered_image",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"ohos.want.action.home"
]
}
]
},
{
"name": "DocumentAbility",
"srcEntry": "./ets/entryability/DocumentAbility.ets",
"description": "$string:DocumentAbility_desc",
"icon": "$media:layered_image",
"label": "$string:DocumentAbility_label",
"launchType": "specified",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background"
}
], Q:如何确认当前打开的UIAbility的数量?
A:可以在UIAbility的生命周期中记录当前已打开的UIAbility数量,示例代码如下:
import { ConfigurationConstant, UIAbility } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; const DOMAIN = 0x0000; // 已打开的UIAbility数量 let uiAbilityNum = 0; export default class WindowsNumAbility extends UIAbility { onCreate(): void { try { this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); } catch (err) { hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err)); } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } onDestroy(): void { hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); // 销毁一个UIAbility时,UIAbility数量减少1,并存入AppStorage uiAbilityNum -= 1; AppStorage.setOrCreate('uiAbilityNum', uiAbilityNum); } onWindowStageCreate(windowStage: window.WindowStage): void { // Main window is created, set main page for this ability hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); // 每次完成WindowStage创建,UIAbility数量增加1,并存入AppStorage uiAbilityNum += 1; AppStorage.setOrCreate('uiAbilityNum', uiAbilityNum); // 第一个窗口加载Index页面,后续新创建的窗口加载NewIndex页面 if (uiAbilityNum === 1) { windowStage.loadContent('pages/Index', (err) => { if (err.code) { hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); return; } hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); }); } else { windowStage.loadContent('pages/NewIndex', (err) => { if (err.code) { hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); return; } hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); }); } } onWindowStageDestroy(): void { // Main window is destroyed, release UI related resources hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); } onForeground(): void { // Ability has brought to foreground hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); } onBackground(): void { // Ability has back to background hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); } };