HarmonyOS Interface (WindowStage) 使用指南:从入门到实战
摘要:
WindowStage是 HarmonyOS 应用窗口管理的核心调度者,负责管理应用的生命周期、页面加载和多窗口协调。本文基于 HarmonyOS NEXT开发实践,系统讲解WindowStage接口的核心方法、生命周期回调和完整示例代码,帮助开发者掌握应用窗口阶段的控制能力。
效果
一、WindowStage 接口概述
WindowStage代表应用的窗口阶段,是 UIAbility 与窗口系统之间的桥梁。每个 UIAbility 在onWindowStageCreate回调中接收一个WindowStage实例,通过它可以:
- 加载应用页面内容
- 获取主窗口实例
- 创建应用子窗口
- 监听窗口事件
- 管理窗口布局与全屏模式
1.1 导入方式
import{window}from'@kit.ArkUI';1.2 获取 WindowStage 实例
WindowStage实例由系统在 UIAbility 生命周期中自动创建并传入,开发者无需手动创建:
exportdefaultclassEntryAbilityextendsUIAbility{onWindowStageCreate(windowStage:window.WindowStage):void{// 此处获取 windowStage 实例}}二、生命周期回调
2.1 onWindowStageCreate
当应用窗口阶段创建时触发,是初始化窗口和加载页面的关键入口。
onWindowStageCreate(windowStage:window.WindowStage):void{hilog.info(0x0000,'app','窗口阶段已创建');// 1. 加载主页面windowStage.loadContent('pages/Index',(err)=>{if(err.code){hilog.error(0x0000,'app','加载失败: %{public}s',JSON.stringify(err));return;}hilog.info(0x0000,'app','页面加载成功');});}2.2 onWindowStageDestroy
当应用窗口阶段销毁时触发,用于释放窗口相关资源。
onWindowStageDestroy():void{hilog.info(0x0000,'app','窗口阶段已销毁');// 清理资源}2.3 完整生命周期流程
UIAbility.onCreate() ↓ UIAbility.onWindowStageCreate(windowStage) ← 窗口阶段创建 ↓ windowStage.loadContent('pages/Index') ← 加载页面 ↓ 页面 aboutToAppear() → build() ← 页面渲染 ↓ UIAbility.onForeground() ← 应用进入前台 ↓ UIAbility.onBackground() ← 应用进入后台 ↓ UIAbility.onWindowStageDestroy() ← 窗口阶段销毁 ↓ UIAbility.onDestroy() ← Ability销毁三、核心方法详解
3.1 loadContent(path, callback)
加载应用主页面内容,是onWindowStageCreate中最核心的调用。
windowStage.loadContent('pages/Index',(err)=>{if(err.code){hilog.error(0x0000,'app','加载失败: %{public}s',JSON.stringify(err));return;}// 页面加载成功后的初始化操作});参数说明:
path:页面路由地址,对应main_pages.json中配置的页面路径callback:加载完成回调,err.code为 0 表示成功
重要提示:
loadContent必须在getMainWindowSync()等方法之前调用,或者在其回调中执行后续操作。
3.2 getMainWindowSync()
同步获取应用主窗口实例。
letmainWindow:window.Window=windowStage.getMainWindowSync();获取主窗口后,可以进行以下操作:
// 获取UI上下文letuiContext=mainWindow.getUIContext();// 获取窗口属性letprops=mainWindow.getWindowProperties();letwindowId=props.id;// 设置全屏mainWindow.setWindowLayoutFullScreen(true);// 获取避让区域letavoidArea=mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);3.3 createSubWindow(name, callback)
在当前窗口阶段创建应用子窗口。
windowStage.createSubWindow('mySubWindow',(err,subWindow)=>{if(err.code){hilog.error(0x0000,'app','创建子窗口失败: %{public}s',err.message);return;}// 子窗口创建成功,进行配置subWindow.setUIContent('subwindow/SubPage',()=>{subWindow.setWindowBackgroundColor('#00000000');});subWindow.moveWindowTo(0,300);subWindow.resize(200,200);subWindow.showWindow();});参数说明:
name:子窗口名称,用于后续通过window.findWindow(name)查找callback:创建回调,返回(err, subWindow)两个参数
注意事项:
- 子窗口名称必须唯一
- 子窗口默认不可见,需调用
showWindow()显示 - 子窗口需要通过
setUIContent设置加载页面
3.4 getMainWindow()
异步获取主窗口(推荐使用getMainWindowSync替代)。
windowStage.getMainWindow((err,mainWindow)=>{if(!err.code){// 使用主窗口}});3.5 getLastWindow(callback)
获取当前应用内最上层的子窗口。
windowStage.getLastWindow((err,topWindow)=>{if(!err.code){hilog.info(0x0000,'app',`最上层窗口ID:${topWindow.getWindowProperties().id}`);}});3.6 setWindowLayoutFullScreen
通过 WindowStage 设置全屏布局(与通过 Window 设置效果一致)。
// 推荐在 loadContent 回调中通过主窗口设置letmainWindow=windowStage.getMainWindowSync();mainWindow.setWindowLayoutFullScreen(true);四、完整示例:WindowStage 综合应用
以下示例展示如何在onWindowStageCreate中完成窗口初始化、全屏设置、避让区域获取、全局上下文存储等操作。
4.1 EntryAbility 完整实现
import{AbilityConstant,ConfigurationConstant,UIAbility,Want}from'@kit.AbilityKit';import{hilog}from'@kit.PerformanceAnalysisKit';import{window}from'@kit.ArkUI';constDOMAIN=0x0000;exportdefaultclassEntryAbilityextendsUIAbility{onCreate(want:Want,launchParam:AbilityConstant.LaunchParam):void{hilog.info(DOMAIN,'app','Ability onCreate');}onDestroy():void{hilog.info(DOMAIN,'app','Ability onDestroy');}onWindowStageCreate(windowStage:window.WindowStage):void{hilog.info(DOMAIN,'app','onWindowStageCreate');// Step 1: 加载主页面windowStage.loadContent('pages/Index',(err)=>{if(err.code){hilog.error(DOMAIN,'app','加载失败: %{public}s',JSON.stringify(err));return;}hilog.info(DOMAIN,'app','页面加载成功');// Step 2: 获取UI上下文并存储到AppStorageletmainWindow=windowStage.getMainWindowSync();letuiContext=mainWindow.getUIContext();AppStorage.setOrCreate('uiContext',uiContext);// Step 3: 存储windowStage供页面使用AppStorage.setOrCreate('windowStage',windowStage);// Step 4: 存储主窗口IDAppStorage.setOrCreate('mainWindowId',mainWindow.getWindowProperties().id);// Step 5: 设置全屏布局mainWindow.setWindowLayoutFullScreen(true);// Step 6: 获取状态栏避让区域letsysAvoidArea=mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);lettopRectHeight=sysAvoidArea.topRect.height;AppStorage.setOrCreate('topRectHeight',topRectHeight);// Step 7: 获取导航条避让区域letnavAvoidArea=mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR);letbottomRectHeight=navAvoidArea.bottomRect.height;AppStorage.setOrCreate('bottomRectHeight',bottomRectHeight);});}onWindowStageDestroy():void{hilog.info(DOMAIN,'app','onWindowStageDestroy');}onForeground():void{hilog.info(DOMAIN,'app','onForeground');}onBackground():void{hilog.info(DOMAIN,'app','onBackground');}}4.2 页面中使用 WindowStage 创建子窗口(状态管理V2版本)
import{window}from'@kit.ArkUI';import{hilog}from'@kit.PerformanceAnalysisKit';@Entry@ComponentV2struct Index{@LocalwindowStage:window.WindowStage=AppStorage.get('windowStage')aswindow.WindowStage;@LocalisSubWindowCreated:boolean=false;// 创建子窗口createSubWindow():void{if(this.isSubWindowCreated){hilog.info(0x0000,'app','子窗口已创建');return;}this.windowStage.createSubWindow('demoSubWin',(err,subWin)=>{if(err.code){hilog.error(0x0000,'app','创建失败: %{public}s',err.message);return;}// 设置子窗口页面subWin.setUIContent('subwindow/SubPage',()=>{subWin.setWindowBackgroundColor('#00000000');});// 设置位置和大小letuiContext=this.windowStage.getMainWindowSync().getUIContext();subWin.moveWindowTo(0,300);subWin.resize(uiContext.vp2px(60),uiContext.vp2px(60));// 显示子窗口subWin.showWindow();this.isSubWindowCreated=true;});}// 销毁子窗口asyncdestroySubWindow():Promise<void>{try{letsubWin=window.findWindow('demoSubWin');awaitsubWin.destroyWindow();this.isSubWindowCreated=false;}catch(err){hilog.error(0x0000,'app','销毁失败: %{public}s',JSON.stringify(err));}}build(){Column({space:20}){Text('WindowStage 示例').fontSize(24).fontWeight(FontWeight.Bold)Button(this.isSubWindowCreated?'销毁子窗口':'创建子窗口').onClick(()=>{if(this.isSubWindowCreated){this.destroySubWindow();}else{this.createSubWindow();}})}.width('100%').height('100%').justifyContent(FlexAlign.Center)}}五、WindowStage 与多窗口协调
5.1 窗口焦点管理
在多窗口场景下,需要管理窗口焦点的切换:
// 将焦点从子窗口转移回主窗口setTimeout(()=>{letsubId=window.findWindow('subWin').getWindowProperties().id;letmainId=windowStage.getMainWindowSync().getWindowProperties().id;window.shiftAppWindowFocus(subId,mainId);},500);5.2 EventHub 事件通信
通过eventHub实现 Ability 与页面之间的事件通信:
// EntryAbility 中发送事件onForeground():void{this.context.eventHub.emit('onForeground');}// 页面中监听事件aboutToAppear():void{letctx=this.getUIContext().getHostContext();ctx?.eventHub.on('onForeground',()=>{// 应用回到前台时的处理逻辑});}aboutToDisappear():void{letctx=this.getUIContext().getHostContext();ctx?.eventHub.off('onForeground');}5.3 通过 AppStorage 实现全局数据共享
WindowStage相关的全局数据推荐通过AppStorage管理:
// 存储AppStorage.setOrCreate('windowStage',windowStage);AppStorage.setOrCreate('uiContext',uiContext);AppStorage.setOrCreate('topRectHeight',topRectHeight);AppStorage.setOrCreate('bottomRectHeight',bottomRectHeight);// 页面中读取@StorageLink('windowStage')windowStage:window.WindowStage;@StorageProp('topRectHeight')topRectHeight:number=0;六、开发要点与最佳实践
6.1 loadContent 回调中的初始化顺序
loadContent 回调 ├── 1. 获取 UIContext 并存储 ├── 2. 存储 WindowStage ├── 3. 设置全屏布局 ├── 4. 获取避让区域高度 └── 5. 其他初始化操作顺序很重要:必须先loadContent成功,再获取主窗口进行后续设置。
6.2 子窗口页面路由配置
子窗口页面需要在main_pages.json中注册:
{"src":["pages/Index","subwindow/SubPage"]}6.3 避免重复创建子窗口
// 创建前检查是否已存在try{letexisting=window.findWindow('subWinName');// 已存在,直接显示existing.showWindow();}catch(err){// 不存在,创建新窗口windowStage.createSubWindow('subWinName',callback);}6.4 应用退出时清理子窗口
onBackground():void{// 应用进入后台时,可选择隐藏或销毁子窗口try{letsubWin=window.findWindow('subWinName');subWin.hideWindow();}catch(err){// 子窗口不存在}}七、WindowStage 接口方法速查表
| 方法 | 说明 | 异步/同步 |
|---|---|---|
loadContent(path, callback) | 加载主页面内容 | 回调 |
getMainWindowSync() | 同步获取主窗口 | 同步 |
getMainWindow(callback) | 异步获取主窗口 | 回调 |
createSubWindow(name, callback) | 创建应用子窗口 | 回调 |
getLastWindow(callback) | 获取最上层子窗口 | 回调 |
setWindowLayoutFullScreen(fullScreen) | 设置全屏布局 | 异步 |
八、总结
WindowStage是 HarmonyOS 应用窗口管理的调度中心,开发者需要重点掌握:
- 生命周期管理:理解
onWindowStageCreate和onWindowStageDestroy的时机 - 页面加载:
loadContent是所有窗口操作的起点 - 主窗口获取:
getMainWindowSync获取主窗口后进行全屏、避让区域等设置 - 子窗口创建:
createSubWindow实现应用内悬浮窗效果 - 全局数据管理:通过
AppStorage在 Ability 和页面间共享窗口信息 - 事件通信:通过
eventHub实现 Ability 与页面的松耦合通信 - 状态管理V2:使用
@ComponentV2+@Local替代 V1 装饰器,与AppStorage.get()配合使用
相关文档:
- Interface (Window) 使用指南
- Interface (AVPlayer) 使用指南
- 简约风格悬浮窗效果案例指南
- ArkTS 悬浮窗开发避坑指南