HarmonyOS鸿蒙Next中仓颉回调函数页面不跳转怎么解决

HarmonyOS鸿蒙Next中仓颉回调函数页面不跳转怎么解决 正常情况下Router.push(url: “MainView”)会跳转第二个界面,但用了回调后就不跳转了,这个不知道哪里出问题了

package ohos_app_cangjie_entry

internal import ohos.base.LengthProp
internal import ohos.component.Column
internal import ohos.component.Row
internal import ohos.component.Button
internal import ohos.component.Text
internal import ohos.component.CustomView
internal import ohos.component.CJEntry
internal import ohos.component.loadNativeView
internal import ohos.state_manage.SubscriberManager
internal import ohos.state_manage.ObservedProperty
internal import ohos.state_manage.LocalStorage
import ohos.state_macro_manage.Entry
import ohos.state_macro_manage.Component
import ohos.state_macro_manage.State
import ohos.state_macro_manage.r
import ohos.router.Router
import std.collection.*
import ohos.net.http.*

@Entry
@Component
class EntryView {
    @State
    var message: String = "Hello Cangjie"
    func build() {
        Row {
            Column {
                Button(message)
                    .onClick {
                        evt =>
                        AppLog.info("Hello Cangjie")
                        RequestApi(
                            "http://xxx.xxxx.xx"
                        ) {
                            res => if (res) {
                                Router.push(url: "MainView")
                            }
                        }
                    }
                    .fontSize(40)
                    .height(80)
            }.width(100.percent)
        }.height(100.percent)
    }
    func RequestApi(url: String, callback: (Bool) -> Unit) {
        let httpRequest = createHttp()
        let option = HttpRequestOptions(
            expectDataType: HttpDataType.STRING,
            header: HashMap<String, String>([("content-type", "application/json")])
        )
        httpRequest.request(
            url,
            {
                err, resp =>
                if (let Some(e) <- err) {
                    callback(false)
                }
                if (let Some(r) <- resp) {
                    callback(true)
                } else {
                    callback(false)
                }
                httpRequest.destroy()
            },
            options: option
        )
    }
}

更多关于HarmonyOS鸿蒙Next中仓颉回调函数页面不跳转怎么解决的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

【解决方案】

httpRequest.request接口设置回调以后会被调到其他线程,使用launch设置到主线程。参考代码:

package ohos_app_cangjie_entry

internal import ohos.base.LengthProp
internal import ohos.component.Column
internal import ohos.component.Row
internal import ohos.component.Button
internal import ohos.component.Text
internal import ohos.component.CustomView
internal import ohos.component.CJEntry
internal import ohos.component.loadNativeView
internal import ohos.state_manage.SubscriberManager
internal import ohos.state_manage.ObservedProperty
internal import ohos.state_manage.LocalStorage
import ohos.state_macro_manage.Entry
import ohos.state_macro_manage.Component
import ohos.state_macro_manage.State
import ohos.state_macro_manage.r
import ohos.router.Router
import ohos.net.http.*
import std.collection.*
import ohos.concurrency.launch

@Entry
@Component
class EntryView {
    @State
    var message: String = "Hello Cangjie"
    func build() {
        Row {
            Column {
                Button(message)
                    .onClick {
                        evt =>
                        AppLog.info("Hello Cangjie")
                        Router.push(url: "MainView")
                    }
                    .fontSize(40)
                    .height(80)

                Button('异步后跳转')
                    .onClick {
                        evt =>
                        AppLog.info("Hello Cangjie")
                        RequestApi("https://www.baidu.com") {
                            res => if (res) {
                                AppLog.info("finish request")
                                launch {Router.push(url: "MainView")}
                            }
                        }
                    }
                    .fontSize(40)
                    .height(80)

            }.width(100.percent)
        }.height(100.percent)
    }

    func RequestApi(url: String, callback: (Bool) -> Unit) {
        let httpRequest = createHttp()
        let option = HttpRequestOptions(
            expectDataType: HttpDataType.STRING,
            header: HashMap<String, String>([("content-type", "application/json")])
        )
        httpRequest.request(
            url,
            {
                err, resp =>
                if (let Some(e) <- err) {
                    callback(false)
                }
                if (let Some(r) <- resp) {
                    callback(true)
                } else {
                    callback(false)
                }
                httpRequest.destroy()
            },
            options: option
        )
    }
}

【背景知识】

  • 仓颉是华为自研的一款面向全场景智能的新一代编程语言,是为HarmonyOS量身打造的全场景智能应用编程语言,旨在支持HarmonyOS系统下的全场景应用开发。
  • 仓颉是一门多范式编程语言,支持函数式、命令式和面向对象等多种范式,支持类型推断,能够降低开发者类型标注的负担;语言内置的各种语法糖和宏(macro)的能力,支持开发者基于仓颉快速开发领域专用语言(DSL),构建领域抽象。

更多关于HarmonyOS鸿蒙Next中仓颉回调函数页面不跳转怎么解决的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


可以了,开始我也试了launch,加错地方了,非常感谢帮我解决问题,

鸿蒙Next中仓颉回调函数页面不跳转,需检查回调函数内是否调用了router.pushUrlrouter.replaceUrl进行页面路由。确保目标页面的路由路径已在module.json5中正确定义。同时,确认回调函数执行未因异常被中断,且页面栈管理正常。

根据你提供的代码,问题很可能出在网络请求的回调没有运行在主线程(UI线程)上。在HarmonyOS Next中,UI操作(包括页面路由跳转)必须在主线程执行,而网络请求的回调通常发生在后台线程。

在你的代码中,httpRequest.request 的回调函数内部直接调用了 Router.push,这可能导致路由跳转因线程问题而失败。

解决方案:

使用 TaskDispatcher 将路由跳转操作派发到主线程执行。修改你的回调部分代码如下:

import ohos.worker.TaskDispatcher
import ohos.worker.Worker

// ... 其他代码保持不变 ...

httpRequest.request(
    url,
    {
        err, resp =>
        if (let Some(e) <- err) {
            callback(false)
        }
        if (let Some(r) <- resp) {
            // 获取主线程任务分发器
            let mainDispatcher: TaskDispatcher = Worker.getMainTaskDispatcher()
            // 将路由跳转派发到主线程执行
            mainDispatcher.asyncDispatch(() => {
                Router.push(url: "MainView")
            })
            callback(true)
        } else {
            callback(false)
        }
        httpRequest.destroy()
    },
    options: option
)

关键修改点:

  1. 在成功回调分支(if (let Some(r) <- resp))内部,不再直接调用 Router.push
  2. 通过 Worker.getMainTaskDispatcher() 获取主线程任务分发器。
  3. 使用 asyncDispatch 方法将包含 Router.push 的闭包派发到主线程异步执行。

其他可能原因及检查点:

  1. 页面路由配置:确保 MainView 页面已在 module.json5 文件中正确配置路由。
  2. 回调条件:确认网络请求确实进入了成功分支(callback(true))。
  3. 错误处理:建议在 if (let Some(e) <- err) 分支中也添加日志输出,以便排查网络请求本身的失败原因。

经过以上修改,路由跳转应该能正常执行。

回到顶部