“HarmonyOS 鸿蒙Next技术问题解析 答开发者问”之第2期
“HarmonyOS 鸿蒙Next技术问题解析 答开发者问”之第2期
HarmonyOS开发者小伙伴们
这里是你们强大的后盾——鸿蒙官方技术支持团队!我们深知在探索鸿蒙开发的旅途中,每一个疑问都可能是前行的绊脚石。因此,我们特别推出了“答开发者问”系列帖,定期筛选并解答大家的问题,旨在为大家答疑解惑,扫清前行路上的障碍。
我们诚挚邀请大家积极发帖,无论是技术上的疑惑,还是开发过程中的瓶颈,都可以在社区中提问交流。同时,我们也鼓励大家互帮互助,如果你有过类似问题的解决经验,不妨慷慨分享,让这份知识和力量传递给更多的开发者。你的每一个提问,每一次解答,都将为鸿蒙生态的发展贡献一份力量。
请持续关注我们的“答开发者问”系列帖,我们会定期更新内容,助开发者一臂之力。让我们携手共进,共创鸿蒙开发的辉煌未来!
本期问题如下:
1、HarmonyOS中的路由跳转该怎么设计?Router和Navigation应该使用哪个呢?
2、使用Navigation导航,当NavPathStack栈内只有1个页面时怎么正确执行退出APP呢?
3、关于replacePath和pushPathByName的问题,用replacePath后返回还是上一个页面是为什么?
4、使用[@BuilderParam](/user/BuilderParam) 之后预览器无法启动是什么原因?
5、元服务如何获取/设置屏幕亮度?
往期问题回顾:
问题一:HarmonyOS中的路由跳转该怎么设计?Router和Navigation应该使用哪个呢?
问题描述:
在HarmonyOS中,如何实现模块间与模块内页面的跳转?Router和Navigation的使用场景是什么?
解决方案:
HarmonyOS提供了两种路由方式,Router和Navigation。Router后续不再继续演进,推荐使用Navigation作为应用的路由方案。两种方案对比如下:
易用性层面:
1.Navigation天然具备标题、内容、回退按钮的功能联动,开发者可以直接使用此能力。Router若要实现此能力,需要自行定义;
2.Navigation的页面是由组件构成,易于实现共享元素的转场。
功能层面:
1.Navigation天然支持一多,Router不支持;
2.Navigation没有路由数量限制,Router限制32个;
3.Navigation可以获取到路由栈NavPathStack,并对路由栈进行操作;
4.Navigation可以嵌套在模态对话框中,也就是说可以模态框中定义路由,Router不支持;
5.Navigation的组件全量由开发者自行控制,开发者可以自定义复杂的动效和属性的设置(背景、模糊等),Router的page对象不对外暴露,开发者无法对page进行处理。
性能层面:
1.Navigation传递参数性能更优,Navigation通过引用传递,Router通过深拷贝完成;
2.Navigation可以配合动态加载,实现组件动态加载,Router页面使用[@Entry](/user/Entry)进行修饰,当前模块加载时会生成全量页面。能力对比详情可参考:
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-router-to-navigation-V5#能力对比
页面跳转参考Navigation路由相关的操作参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-navigation-navigation-V5#路由操作
Router切换Navigation参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-router-to-navigation-V5
原链接:
#HarmonyOS最强问答官# HarmonyOS中的路由跳转有哪些方式?-华为开发者问答 | 华为开发者联盟 (huawei.com)
问题二:使用Navigation导航,当NavPathStack栈内只有1个页面时怎么正确执行退出APP呢?
问题描述:
如下,用@Entry的EntryView作为首页,需要在子页面LofinPage退出APP,但是当我在子页执行pageStack.pop时,以crash的形式退出了APP。请问此时,是否有其他api可以正常退出APP?如何操作?
解决方案:
可以使用terminateSelf退出方法,参考链接:
Button('点击退出').onClick(() => {
let context = getContext(this) as common.UIAbilityContext;
try {
context.terminateSelf((err: BusinessError) => {
if (err.code) {
// 处理业务逻辑错误
console.error(`terminateSelf failed, code is ${err.code}, message is ${err.message}`);
return;
}
// 执行正常业务
console.info('terminateSelf succeed');
});
} catch (err) {
// 捕获同步的参数错误
let code = (err as BusinessError).code;
let message = (err as BusinessError).message;
console.error(`terminateSelf failed, code is ${code}, message is ${message}`);
}
})
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
原链接:
当NavPathStack栈内只有1个页时候怎么正确执行退出?-华为开发者问答 | 华为开发者联盟 (huawei.com)
问题三:关于replacePath和pushPathByName的问题,用replacePath后返回还是上一个页面是为什么?
问题描述:
使用Navigation导航,在首页就使用了replacePath替换页面,之后返回却还是回到了被替换的原页面。明明是替换页面,原页面不是应该不在栈里了吗?为什么返回还能是上一个页面呢?那和pushPathByName 这种不就没区别了吗?
解决方案:
Navigation的内容区默认展示导航内容,即路由栈为空时的首页。
举例比如pageA使用replacePath跳转pageB
若pageA不是通过NavDestination和pageMap注册的路由组件,而是直接写在Navigation内容区,如
Navigation(){
pageA
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
则当路由栈为空时就会展示page。
2、若pageA和pageB都是NavDestination注册的路由页面,则replacePath后pageA的路由栈会被清理,不会再返回pageA
[@Builder](/user/Builder)
pageMap(name: string) {
if (name === 'pageA') {
PageA()
} else if (name === 'pageB') {
PageB()
}
}
build() {
Navigation(this.pageInfo) {
}.navDestination(this.pageMap)
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
问题描述应该是第一种方式,可以修改为第二种方式即可。
原链接:
关于replacePath和pushPathByName的问题-华为开发者问答 | 华为开发者联盟 (huawei.com)
问题四:使用[@BuilderParam](/user/BuilderParam) 之后预览器无法启动是什么原因?
问题描述:
在使用[@BuilderParam](/user/BuilderParam)来接收组件或者使用尾随闭包的时候,出现预览器无法打开的情况是什么原因呢?是只能使用模拟器吗?
[@Entry](/user/Entry)
[@Component](/user/Component)
struct Index {
message?: string;
[@BuilderParam](/user/BuilderParam) myBuilder: () => void;
build() {
Row() {
Column() {
Text(this.message)
this.myBuilder()
}
}
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
解决方案:
使用@BuilderParam时本地入参没有初始化,会导致运行渲染失败。
预览器使用请遵循以下规则:对于所有将被预览到的组件,如果组件的属性支持本地初始化,则都应当设置一个合法的不依赖运行时的默认值,以确保异常调用到该组件时,即使入参不完整,也能正常运行渲染。如下:
@Builder function MyBuilderFunction(): void {}
@Entry
@Component
struct Index {
message?: string = ‘message’;
@BuilderParam myBuilder: () => void = MyBuilderFunction;
build() {
Row() {
Column() {
Text(this.message)
this.myBuilder()
}
}
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
原链接:
使用@BuilderParam 之后预览器无法启动的问题?-华为开发者问答 | 华为开发者联盟 (huawei.com)
问题五:元服务如何获取/设置屏幕亮度?
问题描述:
开发元服务时,需要设置屏幕亮度,发现@system.brightness和@ohos.settings在元服务当中都不支持,有替代api可以实现吗?
解决方案:
推荐使用setWindowBrightness这个接口来设置屏幕亮度,如下:
获取屏幕亮度:
let winProp = window.getWindowProperties()
let brightness = winProp.brightness
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
设置屏幕亮度:
window.setWindowBrightness
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
详细请参考文档:
demo可以参考链接:
原链接:
HarmonyOS 鸿蒙Next技术问题解析
针对“答开发者问”之第2期中的技术问题,以下是专业解答:
-
HarmonyOS中的路由跳转设计:
- 推荐使用Navigation作为应用的路由方案,因其具备标题、内容、回退按钮的功能联动,且页面由组件构成,易于实现共享元素的转场。相较于Router,Navigation在功能层面和性能层面均表现更优。
-
当NavPathStack栈内只有1个页面时正确退出APP:
- 可以使用terminateSelf方法退出APP。示例代码如下:
Button('点击退出').onClick(() => { let context = getContext(this) as common.UIAbilityContext; try { context.terminateSelf((err: BusinessError) => { if (err.code) { console.error(`terminateSelf failed, code is ${err.code}, message is ${err.message}`); } else { console.info('terminateSelf succeed'); } }); } catch (err) { console.error(`terminateSelf failed, code is ${(err as BusinessError).code}, message is ${(err as BusinessError).message}`); } });
- 可以使用terminateSelf方法退出APP。示例代码如下:
以上解答基于HarmonyOS的官方文档和最佳实践。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。希望这些解答能帮助开发者们更好地理解和使用HarmonyOS鸿蒙Next系统。