“HarmonyOS 鸿蒙Next技术问题解析 答开发者问”之第2期

发布于 1周前 作者 vueper 最后一次编辑是 5天前 来自 鸿蒙OS

“HarmonyOS 鸿蒙Next技术问题解析 答开发者问”之第2期

HarmonyOS开发者小伙伴们

这里是你们强大的后盾——鸿蒙官方技术支持团队!我们深知在探索鸿蒙开发的旅途中,每一个疑问都可能是前行的绊脚石。因此,我们特别推出了“答开发者问”系列帖,定期筛选并解答大家的问题,旨在为大家答疑解惑,扫清前行路上的障碍。

我们诚挚邀请大家积极发帖,无论是技术上的疑惑,还是开发过程中的瓶颈,都可以在社区中提问交流。同时,我们也鼓励大家互帮互助,如果你有过类似问题的解决经验,不妨慷慨分享,让这份知识和力量传递给更多的开发者。你的每一个提问,每一次解答,都将为鸿蒙生态的发展贡献一份力量。

请持续关注我们的“答开发者问”系列帖,我们会定期更新内容,助开发者一臂之力。让我们携手共进,共创鸿蒙开发的辉煌未来!

本期问题如下:

1、HarmonyOS中的路由跳转该怎么设计?Router和Navigation应该使用哪个呢?

2、使用Navigation导航,当NavPathStack栈内只有1个页面时怎么正确执行退出APP呢?

3、关于replacePath和pushPathByName的问题,用replacePath后返回还是上一个页面是为什么?

4、使用[@BuilderParam](/user/BuilderParam) 之后预览器无法启动是什么原因?

5、元服务如何获取/设置屏幕亮度?

往期问题回顾:

“答开发者问”之HarmonyOS技术问题解析 第1期-华为开发者问答 | 华为开发者联盟 (huawei.com)

6 回复

问题一: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?如何操作?

cke_18938.png

cke_19215.png

解决方案:

可以使用terminateSelf退出方法,参考链接:

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-inner-application-uiabilitycontext-V5#uiabilitycontextterminateself

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>

问题描述应该是第一种方式,可以修改为第二种方式即可。

原链接:

关于replacePathpushPathByName的问题-华为开发者问答 | 华为开发者联盟 (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>

参考文档: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-previewer-previewchecker-V5#section2419195511515

原链接:

使用@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>

详细请参考文档:

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-window-V5#setwindowbrightness9

demo可以参考链接:

https://gitee.com/winslei/harmony-os_-winsleikit/blob/master/entry/src/main/ets/pages/Window/WindowHome.ets

原链接:

元服务如何获取/设置屏幕亮度-华为开发者问答 | 华为开发者联盟 (huawei.com)

HarmonyOS 鸿蒙Next技术问题解析

针对“答开发者问”之第2期中的技术问题,以下是专业解答:

  1. HarmonyOS中的路由跳转设计

    • 推荐使用Navigation作为应用的路由方案,因其具备标题、内容、回退按钮的功能联动,且页面由组件构成,易于实现共享元素的转场。相较于Router,Navigation在功能层面和性能层面均表现更优。
  2. 当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}`);
        }
      });
      

以上解答基于HarmonyOS的官方文档和最佳实践。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。希望这些解答能帮助开发者们更好地理解和使用HarmonyOS鸿蒙Next系统。

回到顶部