HarmonyOS 鸿蒙Next中为啥WindowManager.getWindowStage().getMainWindow()获取不到主窗口?

HarmonyOS 鸿蒙Next中为啥WindowManager.getWindowStage().getMainWindow()获取不到主窗口?

如下代码是想要修改状态栏颜色,为啥WindowManager.getWindowStage().getMainWindow()获取不到主窗口?

aboutToAppear(): void {
    // 设置主窗口状态栏的属性,使用Promise异步回调
    // https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowsystembarproperties9
    let SystemBarProperties: window.SystemBarProperties = {
      statusBarColor: '#ff00ff',
      navigationBarColor: '#00ff00',
      statusBarContentColor: '#ff5500',
      navigationBarContentColor: '#00ffff'
    };
    try {
      console.debug('ztq', `mainWin --- ${JSON.stringify(this.mainWin)}`)
      console.debug('ztq', `mainWin --- ${JSON.stringify(WindowManager.getWindowStage().getMainWindow())}`) // 无输出
      WindowManager.getWindowStage().getMainWindow().then((win) => {
        console.debug('ztq', `win  ---  ${JSON.stringify(win)}`) // 无输出
        win.setWindowSystemBarProperties(SystemBarProperties);
      })
    } catch (exception) {
      console.error(`Failed to set the system bar properties. Cause code: ${exception.code}, message: ${exception.message}`);
    }
  }

然后,我把onWindowStageCreate中的windowStage存下来,通过如下代码,就可以获取到主窗口并且修改状态栏颜色,那为啥WindowManager.getWindowStage().getMainWindow()获取不到主窗口呢?

windowStage: window.WindowStage = AppStorage.get("windowStage") as window.WindowStage;
// 获取主窗口的方式
mainWin: window.Window = this.windowStage.getMainWindowSync();
aboutToAppear(): void {
    // 设置主窗口状态栏的属性,使用Promise异步回调
    // https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowsystembarproperties9
    let SystemBarProperties: window.SystemBarProperties = {
      statusBarColor: '#ff00ff',
      navigationBarColor: '#00ff00',
      statusBarContentColor: '#ff5500',
      navigationBarContentColor: '#00ffff'
    };
    try {
      let promise = this.mainWin.setWindowSystemBarProperties(SystemBarProperties);
      promise.then(() => {
        console.info('Succeeded in setting the system bar properties.');
      }).catch((err: BusinessError) => {
        console.error(`Failed to set the system bar properties. Cause code: ${err.code}, message: ${err.message}`);
      });
    } catch (exception) {
      console.error(`Failed to set the system bar properties. Cause code: ${exception.code}, message: ${exception.message}`);
    }
  }

更多关于HarmonyOS 鸿蒙Next中为啥WindowManager.getWindowStage().getMainWindow()获取不到主窗口?的实战教程也可以访问 https://www.itying.com/category-93-b0.html

8 回复

setWindowStage: 设置窗口管理器,在EntryAbility的onWindowStageCreate方法中调用

更多关于HarmonyOS 鸿蒙Next中为啥WindowManager.getWindowStage().getMainWindow()获取不到主窗口?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


应该是WindowManager.getWindowStage()的有效上下文需要在WindowStage创建完成后才能正常调用。在aboutToAppear生命周期阶段,可能还没有完成WindowStage的初始化流程。你试试在onWindowStageCreate生命周期回调中保存WindowStage实例到AppStorage,然后再通过同步方法getMainWindowSync()获取主窗口对象。

// 存储WindowStage实例
onWindowStageCreate(windowStage: window.WindowStage) {
  windowStage.loadContent('pages/Index', (err) => {
    AppStorage.setOrCreate("windowStage", windowStage);
  });
}

// 页面中获取主窗口
private mainWin: window.Window = AppStorage.get("windowStage").getMainWindowSync();

老哥你这个方法是好使的,我上面也有提到,当时纳闷儿为啥WindowManager.getWindowStage().getMainWindow()获取不到主窗口?没事的,已经解决了,就是没有设置窗口管理器-setWindowStage

明白了,需要在onWindowStageCreate这个生命周期中调用setWindowStage

onWindowStageCreate(windowStage: window.WindowStage): void {
    WindowManager.setWindowStage(windowStage)
}
let windowStage = AppStorage.get("windowStage") as window.WindowStage
let windowClass: window.Window = windowStage.getMainWindowSync()

这个方法是好使的,但是俺想知道为啥WindowManager.getWindowStage().getMainWindow()获取不到主窗口啊,用这个属性获取主窗口就不能修改状态栏属性,

在鸿蒙Next中,WindowStage.getMainWindow()获取不到主窗口可能是以下原因:

  1. 调用时机过早,窗口尚未完成初始化
  2. 当前Page Ability未关联到WindowStage
  3. 未正确设置WindowStage的窗口模式

确保在onWindowStageCreate回调触发后调用该方法。检查Ability的配置是否包含"window"属性,且窗口模式设置为WINDOW_MODE_FULLSCREEN

在HarmonyOS Next中,WindowManager.getWindowStage().getMainWindow() 获取不到主窗口可能是因为调用时机问题。WindowStage 的生命周期管理较为严格,在 aboutToAppear 阶段窗口可能尚未完全初始化完成。

正确的做法是在 onWindowStageCreate 回调中获取并保存 WindowStage 实例,正如你后面采用的方式。这是因为:

  1. onWindowStageCreate 是窗口阶段创建时的明确生命周期回调,此时 WindowStage 已完全初始化。
  2. getMainWindowSync() 是同步方法,能立即返回窗口对象。
  3. 通过 AppStorage 保存 WindowStage 实例可以确保后续随时获取。

建议始终使用在 onWindowStageCreate 中保存 WindowStage 的方式,这是官方推荐的做法。异步获取窗口的方式 (getMainWindow()) 在某些生命周期阶段可能无法保证能获取到有效窗口对象。

你的第二种实现方案是正确的,这种方式能可靠地获取到主窗口并修改状态栏属性。

回到顶部