HarmonyOS 鸿蒙Next中Surface生命周期内获取的window指针为空是为什么?
HarmonyOS 鸿蒙Next中Surface生命周期内获取的window指针为空是为什么?
/**
* Surface变化回调函数
* @param component XComponent组件
* @param window 窗口句柄
*/
static void OnSurfaceChanged(OH_NativeXComponent *component, void *window)
{
LAppPal::PrintLogLn("Start OnSurfaceChanged.");
if (!CheckComponent(component))
{
LAppPal::PrintLogLn("OnSurfaceChanged failed.");
return;
}
// 获取XComponent尺寸
int32_t ret = OH_NativeXComponent_GetXComponentSize(g_NativeXComponent, window, &width, &height);
if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS)
{
// 更新显示尺寸
OH_LOG_INFO(LOG_APP, "OnSurfaceChanged GetXComponentSize failed. ret = %{public}d", ret);
} else {
OH_LOG_INFO(LOG_APP, "OnSurfaceChanged GetXComponentSize: %{public}d, %{public}d", width, height);
}
if (!window)
{
OH_LOG_INFO(LOG_APP, "OnSurfaceChanged Window failed.");
return;
}
// 标记Surface已变化
g_IsSurfaceChanged = true;
}
以下是运行日志

更多关于HarmonyOS 鸿蒙Next中Surface生命周期内获取的window指针为空是为什么?的实战教程也可以访问 https://www.itying.com/category-93-b0.html
您好,应用闪退的crash栈是liblive2dcubismcore.so上,和xc没什么关系;另外在闪退的库上加日志排查,SurfaceHolder渲染测试不走这个逻辑,仅NatieXComponent渲染测试走这个逻辑;您可以排查下live2d_framework这个库的问题。
更多关于HarmonyOS 鸿蒙Next中Surface生命周期内获取的window指针为空是为什么?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
您好,代码里XComponentTest.cpp的XComponent创建时机不正确,导致xc未能正确初始化,建议调整代码顺序,把g_childXComponent = new XComponent(ARKUI_NODE_XCOMPONENT);放到CreateNativeNode方法中即可。
闪退的crash栈是liblive2dcubismcore.so上,但是主要问题不是闪退啊,是native侧创建的xc的suface生命周期里获取到的window指针是空的,导致NatieXComponent渲染测试没办法正常初始化egl,不能渲染需要的画面啊
而且闪退是因为同时使用了两个渲染测试才崩溃的吧,这个demo只有单例渲染,两个一起测试就会崩溃
您好,您可以按照以下排查,或者可以发下完整代码嘛
1、根据错误日志,可以看到OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER = -2原因为错误参数,根据描述问题出现在windows对象上。 2、根据现有代码没法看出windows对象是如何传入的,请问下可以给出完整代码嘛 或者提前做一下window对象的校验。 3、建议检查下OH_ArkUI_SurfaceCallback_SetSurfaceChangedEvent方法中注册的回调是否是当前的onSurfaceChanged方法以此来检验下windows对象是否合法。
我这个是native侧创建的xcomponent,直接注册的xcomponentcallback的,回调里自己带的window就是空的,
您好,请问下当前的代码调用场景是什么,可以检查下是否在调用surfaceChange之前调用了surfaceCreate方法,这种也是会造成参数异常的。另外方便提供下完整代码嘛,
最小demo现在不太好拆,比之前代码写多了,就是native侧创建xcomponent后xcomponent注册回调,然后在arkts侧将nodecontent传到native侧,并将xcomponent挂载到这个node上,然后自动触发created这些surface生命周期回调函数,但是无论是created还是changed里面的window都是空指针,无效参数。
window 为空的可能原因
根据 API 头文件 native_interface_xcomponent.h 的定义,OnSurfaceChanged 回调中的 void* window 参数是 native window handler(原生窗口句柄)。以下是它可能为空的几个原因:
-
Surface 生命周期时序问题(最常见) OnSurfaceChanged 可能在 OnSurfaceCreated 之前被调用,或者在 Surface 尚未完全初始化时触发。正常生命周期顺序应该是: OnSurfaceCreated → OnSurfaceChanged → … → OnSurfaceDestroyed 但在某些场景下(如快速切换页面、屏幕旋转),系统可能在 Surface 未完全创建的情况下就触发了 Changed 回调。
-
autoInitialize 配置问题 从 API 19 文档(头文件第 1232-1235 行)可以看到: If the value is true, OnSurfaceCreated will be called when the node is mounted and OnSurfaceDestroyed will be called when the node is unmounted. Default value is true. 如果 autoInitialize 被设为 false,或者 XComponent 节点挂载顺序异常,window 可能不会被正确传入。
-
XComponent 的 type 配置不正确 XComponent 有不同的 type(surface、component、texture)。如果 type 不是 surface,回调中的 window 行为可能不同。确保 XComponent 声明使用的是 surface 类型。
-
代码中的逻辑问题 你的代码在检查 window 是否为空 之前 就调用了 OH_NativeXComponent_GetXComponentSize(g_NativeXComponent, window, &width, &height)。如果 window 确实为空,这个调用本身就可能产生未定义行为。
建议修复
static void OnSurfaceChanged(OH_NativeXComponent *component, void *window)
{
LAppPal::PrintLogLn("Start OnSurfaceChanged.");
if (!CheckComponent(component))
{
LAppPal::PrintLogLn("OnSurfaceChanged failed.");
return;
}
// 先检查 window 是否有效
if (!window)
{
OH_LOG_INFO(LOG_APP, "OnSurfaceChanged: window is null, skipping.");
return;
}
// window 有效后再获取尺寸
int32_t ret = OH_NativeXComponent_GetXComponentSize(g_NativeXComponent, window, &width, &height);
if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS)
{
OH_LOG_INFO(LOG_APP, "OnSurfaceChanged GetXComponentSize failed. ret = %{public}d", ret);
} else {
OH_LOG_INFO(LOG_APP, "OnSurfaceChanged GetXComponentSize: %{public}d, %{public}d", width, height);
}
g_IsSurfaceChanged = true;
}
排查建议
- 在 OnSurfaceCreated 中打印 window 指针值,确认它是否正常获取到
- 检查 XComponent 的 ArkTS 侧声明,确认 type 为 XComponentType.SURFACE
- 如果目标 API Level >= 19,考虑迁移到新的 OH_ArkUI_SurfaceHolder API,它提供了更好的类型安全和生命周期管理
在HarmonyOS Next中,Surface生命周期内获取的window指针为空,通常是因为Surface尚未与窗口完成绑定或窗口尚未初始化完成。Surface的可用性依赖于其关联的Window对象的状态。若在Window未就绪(如未完成创建或已销毁)时访问,获取的指针即为空。需确保在Window的onWindowCreated回调之后或Surface已有效附加到窗口时再进行相关操作。
在HarmonyOS Next中,OnSurfaceChanged回调函数接收到的window指针为空,通常是由于XComponent的Surface生命周期与窗口句柄的异步管理导致的。根据你提供的日志,OH_NativeXComponent_GetXComponentSize返回了错误码-3(对应OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER),这进一步证实了传入的window参数无效。
主要原因如下:
-
Surface销毁或未就绪:
OnSurfaceChanged可能在Surface真正关联到有效窗口之前被触发,例如在Surface即将销毁(OH_NATIVEXCOMPONENT_SURFACE_DESTROY)或初始化未完成时。此时窗口句柄可能已被释放或尚未分配。 -
回调触发时机问题:HarmonyOS Next的XComponent生命周期中,Surface变化事件(如尺寸调整、重建)可能多次触发,某些触发点(尤其是销毁阶段)并不保证携带有效的
window指针。 -
组件未正确挂载:如果XComponent对应的UI组件未完全挂载到视图树或处于不可见状态,其底层的Surface可能无法获取到有效的窗口资源。
解决建议:
- 在回调中优先检查
window指针有效性,若为空则直接返回,避免后续操作(如示例代码已实现)。 - 确保仅在
OH_NATIVEXCOMPONENT_SURFACE_CREATED或OH_NATIVEXCOMPONENT_SURFACE_CHANGED事件中处理关键逻辑,避免在销毁阶段依赖窗口句柄。 - 通过
OH_NativeXComponent_RegisterCallback注册生命周期回调时,确认所有回调函数(如OnSurfaceCreated、OnSurfaceDestroyed)均正确实现,以区分不同事件。
根据日志,你的代码已对空指针做了防护,但需进一步排查XComponent的初始化流程和Surface事件触发条件,确保在窗口资源有效时才执行GetXComponentSize等操作。

