HarmonyOS鸿蒙Next中调用promptAction.openCustomDialog闪退

HarmonyOS鸿蒙Next中调用promptAction.openCustomDialog闪退 在一个对象里面封装了一个showDialog方法如下:

showDialog(uiContext: UIContext){
  const promptAction=uiContext.getPromptAction()
  promptAction.openCustomDialog({
    builder: ()=>{
      CustomOpenDialog()
    }
  }).catch((err:BusinessError) => {
    console.log("err",JSON.stringify(err))
  })
}

然后builder中的CustomOpenDialog是一个写在页面外面的函数:

@Builder
export function CustomOpenDialog() {
  Column() {
    Text("弹窗")
  }
}

写在一个页面文件里面,但是不在@Entry @Component struct 里面

然后在对象里面有另一个函数如test调用上面的showDialog打开弹窗,之后导出对象,

在某个页面上的按钮点击事件里面触发test函数,但是应用直接闪退

报错信息如下:Error message:Cannot read property observeComponentCreation2 of undefined


更多关于HarmonyOS鸿蒙Next中调用promptAction.openCustomDialog闪退的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

【背景知识】 ArkUI提供了一种轻量的UI元素复用机制@Builder,其内部UI结构固定,仅与使用方进行数据传递,开发者可以将重复使用的UI元素抽象成一个方法,在build方法里调用。

【解决方案】 自定义构建函数@Builder可以在所属组件的build方法和其他自定义构建函数中调用,但不允许在组件外调用。因此,需要将自定义构建函数@Builder移至结构体内部,示例代码如下:

import { promptAction } from '@kit.ArkUI'

@Entry
@Component
struct Index {
  // 在结构体内构建定义函数
  [@Builder](/user/Builder)
  customDialogComponent() {
    Column() {
      Text('customDialogComponent')
    }
  }

  build() {
    Column() {
      Button('弹窗').onClick(() => {
        promptAction.openCustomDialog({
          builder: () => {
            this.customDialogComponent()
          },
          alignment: DialogAlignment.Center
        })
      })
    }
  }
}

更多关于HarmonyOS鸿蒙Next中调用promptAction.openCustomDialog闪退的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中调用promptAction.openCustomDialog发生闪退,可能由以下原因导致:参数配置错误、自定义弹窗组件未正确声明或资源ID引用异常。检查弹窗布局文件是否存在且路径正确,确认promptAction模块已导入。排查组件生命周期与弹窗显示时机的冲突,确保在UI线程执行。若使用ArkTS开发,验证装饰器语法和状态变量绑定。

从错误信息Cannot read property observeComponentCreation2 of undefined来看,这是典型的UI组件上下文丢失问题。在HarmonyOS Next中,[@Builder](/user/Builder)函数需要正确的UI上下文才能正常渲染。

问题分析:

  1. 你的CustomOpenDialog被定义为export的全局[@Builder](/user/Builder)函数
  2. 当通过封装对象调用时,[@Builder](/user/Builder)函数失去了与当前UI组件的关联
  3. promptAction.openCustomDialog中的builder参数无法获取到有效的组件上下文

解决方案:

方案一:将@Builder函数移到组件内部

@Entry
@Component
struct MyPage {
  [@Builder](/user/Builder) CustomOpenDialog() {
    Column() {
      Text("弹窗")
    }
  }

  // 在组件内调用showDialog时传递this
  showDialog() {
    const promptAction = getUIContext().getPromptAction()
    promptAction.openCustomDialog({
      builder: () => {
        this.CustomOpenDialog()
      }
    }).catch((err: BusinessError) => {
      console.log("err", JSON.stringify(err))
    })
  }
}

方案二:使用组件实例调用@Builder函数

// 在封装对象中接收组件实例
showDialog(component: any) {
  const promptAction = getUIContext().getPromptAction()
  promptAction.openCustomDialog({
    builder: () => {
      component.CustomOpenDialog()
    }
  })
}

推荐使用方案一,确保[@Builder](/user/Builder)函数始终在正确的UI上下文中执行。全局的[@Builder](/user/Builder)函数在跨组件调用时容易出现上下文丢失问题。

回到顶部