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
【解决方案】
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.pushUrl或router.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
)
关键修改点:
- 在成功回调分支(
if (let Some(r) <- resp))内部,不再直接调用Router.push。 - 通过
Worker.getMainTaskDispatcher()获取主线程任务分发器。 - 使用
asyncDispatch方法将包含Router.push的闭包派发到主线程异步执行。
其他可能原因及检查点:
- 页面路由配置:确保
MainView页面已在module.json5文件中正确配置路由。 - 回调条件:确认网络请求确实进入了成功分支(
callback(true))。 - 错误处理:建议在
if (let Some(e) <- err)分支中也添加日志输出,以便排查网络请求本身的失败原因。
经过以上修改,路由跳转应该能正常执行。

