HarmonyOS鸿蒙Next中扫码成功后调用router.pushUrl无效

HarmonyOS鸿蒙Next中扫码成功后调用router.pushUrl无效

问题描述

调用 scanBarcode.startScanForResult 扫码成功后,调用 router.push 无反应。看打印信息都走到了成功的回调中,但是页面无跳转。

import { scanBarcode } from '@kit.ScanKit'
import { BusinessError } from '@kit.BasicServicesKit'

@Entry
struct MainTabPage {
  router = this.getUIContext().getRouter()
  context = this.getUIContext().getHostContext()

  private onScanCode(): void {
    scanBarcode.startScanForResult(this.context).then((result) => {
      console.info('onScanCode result:', JSON.stringify(result))
      this.router.pushUrl({ url: 'pages/web/WebPage', params: { code: result.originalValue } })
        .then(() => {
          console.info('onScanCode pushUrl success')
        })
        .catch((err: BusinessError) => {
          console.error('onScanCode pushUrl err:', JSON.stringify(err))
        })
    }).catch((err: BusinessError) => {
      console.error('onScanCode err:', JSON.stringify(err))
    })
  }

  private onPushUrl() {
    this.router.pushUrl({ url: 'pages/web/WebPage'})
      .then(() => {
        console.info('onPushUrl pushUrl success')
      })
      .catch((err: BusinessError) => {
        console.error('onPushUrl pushUrl err:', JSON.stringify(err))
      })
  }

  build() {
    Column({ space: '20lpx' }) {
      Button() {
        Text('扫码跳转')
      }.onClick(() => {
        this.onScanCode()
      })

      Button() {
        Text('直接跳转')
      }.onClick(() => {
        this.onPushUrl()
      })
    }
    .width('100%')
    .height('100%')
    .alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
  }
}
  • 打印信息
2-23 09:39:11.305   47255-47255   A03D00/com.exa...harmony/JSAPP  com.examp..._harmony  I     onScanCode result: {"scanType":10,"originalValue":"some value..."}
12-23 09:39:11.308   47255-47255   A03D00/com.exa...harmony/JSAPP  com.examp..._harmony  I     onScanCode pushUrl success

运行环境

  • sdk版本:5.0.3(15)

运行设备

  • 设备名称:nova 16
  • HarmonyOS版本:6.0.0

更多关于HarmonyOS鸿蒙Next中扫码成功后调用router.pushUrl无效的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

你好,尝试使用 setTimeout 延时500毫秒后再做跳转。

private onScanCode(): void {
  scanBarcode.startScanForResult(this.context).then((result) => {
    console.info('onScanCode result:', JSON.stringify(result))
    setTimeout(()=>{
      this.onPushUrl()
    },500)
  }).catch((err: BusinessError) => {
    console.error('onScanCode err:', JSON.stringify(err))
  })
}

更多关于HarmonyOS鸿蒙Next中扫码成功后调用router.pushUrl无效的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


你好,这个方案已经尝试了,还是无法跳转。我打印了跳转后的当前路由堆栈信息,发现虽然 router.push 走到了成功的回调中,但是路由堆栈信息总没有新跳转的页面的数据

private onScanCode(): void {
    scanBarcode.startScanForResult(this.context).then((result) => {
      console.info('onScanCode result:', JSON.stringify(result))
      setTimeout(() => {
        this.router.pushUrl({ url: 'pages/web/WebPage', params: { code: result.originalValue } })
          .then(() => {
            console.info('Current Router State:', JSON.stringify(this.router.getState()))
            console.info('Current Router Length:', this.router.getLength())
            console.info('onScanCode pushUrl success')
          })
          .catch((err: BusinessError) => {
            console.error('onScanCode pushUrl err:', JSON.stringify(err))
          })
      }, 1000)
    }).catch((err: BusinessError) => {
      console.error('onScanCode err:', JSON.stringify(err))
    })
  }

答应信息

12-23 10:12:18.982   20882-20882   A03D00/com.exa...harmony/JSAPP  com.examp..._harmony  I     Current Router State: {"index":1,"name":"MainTabPage","path":"pages/main/"}
12-23 10:12:18.982   20882-20882   A03D00/com.exa...harmony/JSAPP  com.examp..._harmony  I     Current Router Length: 1,

是我这边跳转目标页面逻辑的bug,感谢回答。,

实测系统6.0,SDK6.0.0

直接复制你的代码,扫码后可正常跳转

在HarmonyOS Next中,扫码成功后调用router.pushUrl无效,通常是因为页面路由栈管理或页面生命周期问题。请检查扫码页面是否已正确配置路由,并确保在扫码成功的回调函数中调用router.pushUrl。同时,确认目标页面的路由路径是否正确,以及是否在main_pages.json中注册。

这个问题通常是由于 scanBarcode.startScanForResult 的调用上下文导致的。在扫码成功后,then 回调中的 this 指向可能发生了变化,导致 this.routerundefined 或指向了错误的 router 对象,因此 pushUrl 调用无效。

从你的代码看,onScanCode 方法中使用了 this.router,但在 Promise 的 then 回调里,this 的上下文已经丢失。虽然日志打印了成功信息,但实际的 router.pushUrl 可能因为 this.router 无效而静默失败。

解决方案:

在调用 startScanForResult 之前,将正确的 this 引用保存到一个局部变量中(例如 that),然后在 then 回调中使用这个变量来访问 router

修改后的 onScanCode 方法示例:

private onScanCode(): void {
  const that = this; // 保存当前上下文的引用
  scanBarcode.startScanForResult(this.context).then((result) => {
    console.info('onScanCode result:', JSON.stringify(result))
    that.router.pushUrl({ url: 'pages/web/WebPage', params: { code: result.originalValue } }) // 使用 that.router
      .then(() => {
        console.info('onScanCode pushUrl success')
      })
      .catch((err: BusinessError) => {
        console.error('onScanCode pushUrl err:', JSON.stringify(err))
      })
  }).catch((err: BusinessError) => {
    console.error('onScanCode err:', JSON.stringify(err))
  })
}

或者,你也可以使用箭头函数来定义 onScanCode 方法,以确保方法内部的 this 绑定正确,但上述显式保存 this 引用的方法是最直接可靠的。

原因分析: startScanForResult 会启动一个系统的扫码界面,这是一个异步且可能涉及跨进程的交互。当扫码完成,Promise 的 then 回调被执行时,其执行上下文可能已不再是原来的 ArkTS UI 组件实例。因此,通过 this.router 无法获取到正确的路由对象,导致页面跳转失败。而你的 onPushUrl 方法能正常工作,是因为它由按钮点击直接触发,this 上下文保持正确。

回到顶部