HarmonyOS笔记9:UIAbility之间的切换和数据的传递

HarmonyOS Next的UIAbility是 HarmonyOS Next中应用程序用户界面的一个基本构建单元。可将其理解为一个拥有自己生命周期和用户界面的"页面"或"屏幕"。它管理ArkTS 和 ArkUI 框架构建界面。并在能够在一个独立的屏幕上完成某项任务。在一个HarmonyOS移动应用中可以定义一个或多个UIAbility子类。在不同的UIAbility之间进行切换和实现数据的传递。

在本文中,将对这两种情况结合一个简单的例子进行介绍。:

一、Want是UIAbility切换的基础

UIAbility的数据传递可以通过Want来实现的。HarmonyOS 的 Want 是系统内对象间信息传递的载体,主要用于组件(Ability)间通信。它可以理解为一种消息或请求。Want 封装了目标组件信息、携带的数据和操作类型,是 HarmonyOS 跨组件通信的基础。

首先,创建一个HarmonyOS项目,在默认的entry模块中会创建对应的顶层UIAbility,在本例中命名为UIAbilityApp04Ability(UIAbilityApp04与模块的名称相同)。定层的UIAbility默认加载的页面是Index.ets。

现在,我们在顶层的UIAbility的页面Index.ets中定义了两个按钮,分别实现两种不同页面的切换和参数的传递:

(1)切换到其他页面并发送相应的数据;

(2)切换到其他页面,但是这个页面可以返回顶层UIAbility,并返回参数。

typescript 复制代码
import Want from '@ohos.app.ability.Want';
import { BusinessError } from '@ohos.base';
import { common } from '@kit.AbilityKit';

@Entry
@Component
struct Index {
  private context = this.getUIContext().getHostContext() as common.UIAbilityContext;

  @State firstMsg:string = ""
  build() {
    Column() {
      Text(`${this.firstMsg}`)
        .fontSize(30)
        .fontColor(Color.Green)

      Button("跳转到FIRSTABILITY")
        .onClick(()=>{
          let want: Want = {
            deviceId: "", // 空表示本设备
            bundleName: "cn.edu.ncu.harmonyos.ch01", //同app.json5
            abilityName: "FirstAbility",
            parameters: {
              // 传递参数
              "key1": "value1",
              "key2": 100
            }
          };
          this.context.startAbility(want)
        })

      Button("跳转到OtherABILITY")
        .onClick(()=>{
          let want:Want = {
            deviceId:"",
            bundleName:"cn.edu.ncu.harmonyos.ch01",
            abilityName:"OtherAbility"
          }
          this.context.startAbilityForResult(want).then((data)=>{
            if(data.want?.parameters){
              this.firstMsg = `${data.want.parameters['result']}`;
            }
          })
        })
    }
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
    .height('100%')
    .width('100%')
  }
}

在上述的Index.ets定义的页面中,包含了两个按钮,这两个按钮分别实现:

(1)切换其他界面并发送数据;

let want: Want = {

deviceId: "", // 空表示本设备

bundleName: "cn.edu.ncu.harmonyos.ch01", //同app.json5

abilityName: "FirstAbility",

parameters: {

// 传递参数

"key1": "value1",

"key2": 100

}

};

this.context.startAbility(want)

(2)带结果启动其他UIAbility,并接受返回时带回的数据;

let want:Want = {

deviceId:"",

bundleName:"cn.edu.ncu.harmonyos.ch01",

abilityName:"OtherAbility"

}

this.context.startAbilityForResult(want).then((data)=>{

if(data.want?.parameters){

this.firstMsg = ${data.want.parameters['result']};

}

})

})

其他自定义的UIAbility可以通过DevEco Studio的新建-》Ability来实现。如图1所示:

图2 创建自定义Ability的界面。

二、定义数据的接受方的UIAbility

定义接受顶层UIAbility传递的参数的UIAbility,在此处命名为FirstAbility,在FirstAbility的onCreate方法中增加参数接受的代码,具体如下:

typescript 复制代码
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';

const DOMAIN = 0x0000;

export default class FirstAbility extends UIAbility {

  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
    globalThis.wantData = want.parameters
    // 接收传递的参数,并在日志显示
    if (want.parameters) {
      const key1 = want.parameters['key1'];
      const key2 = want.parameters['key2'];
      hilog.info(DOMAIN,'testTag',`接收参数: key1=${key1}, key2=${key2}`);
    }
  }
  onWindowStageCreate(windowStage: window.WindowStage): void {
    // Main window is created, set main page for this ability
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    windowStage.loadContent('pages/FirstPage', (err) => {
      if (err.code) {
        hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
        return;
      }
      hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
    });
  }
 ...//略
 }

在FirstAbility中,通过globalThis.wantData = want.parameters,获取传递的参数。如果要让这个参数在对应的页面中显示,则需要在页面显示的部分进行参数内容的获取,具体的代码如下:

typescript 复制代码
@Entry
@Component
struct FirstPage {
  @State message :string = ""

  onPageShow(){
    this.message = `获取关键字1:${globalThis.wantData['key1']}-关键字2:${globalThis.wantData['key2']}`;
  }
  build() {
    Column() {
      Text("接受参数")
        .fontSize($r("app.float.page_text_font_size"))
        .fontWeight(FontWeight.Bold)

      Text(this.message)
        .fontSize($r('app.float.page_text_font_size'))
        .fontWeight(FontWeight.Bold)
    }
    .height('100%')
    .width('100%')
  }
}

在onPageShow()显示页面的处理中,利用"globalThis.wantData['key1'] "和"globalThis.wantData['key1']"获取了传递的参数。

三、UIAbility带参数的返回

在顶层UIAbility中,还通过调用"startAbilityForResult"方法,启动OtherAbility,希望OtherAbility能带结果返回。因此定义的OtherAbility加载的OtherPage页面的代码如下:

typescript 复制代码
import { common } from '@kit.AbilityKit';

@Entry
@Component
struct OtherPage {
  @State message: string = 'OtherAbility';

  build() {
    Column() {
      Text(this.message)
        .id('HelloWorld')
        .fontSize($r('app.float.page_text_font_size'))
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })

        Button("返回UIAbilityApp04Ability")
        .onClick(() => {
          let context = this.getUIContext().getHostContext() as common.UIAbilityContext
          const RESULT_CODE:number = 1001;
          let abilityResult:common.AbilityResult = {
            resultCode:RESULT_CODE,
            want:{
              bundleName:"cn.edu.ncu.harmonyos.ch01",
              abilityName:"UIAbilityApp04Ability",
              parameters:{
                result:"来自OtherAbility的问候"
              }
            }
          }
          context.terminateSelfWithResult(abilityResult,(err)=>{
            if(err.code){
              console.log(`出现错误`)
            }
          })
        })
    }
    .height('100%')
    .width('100%')
  }
}

在如下代码定义了返回的结果:

let context = this.getUIContext().getHostContext() as

common.UIAbilityContext

const RESULT_CODE:number = 1001;

let abilityResult:common.AbilityResult = {

resultCode:RESULT_CODE,

want:{

bundleName:"cn.edu.ncu.harmonyos.ch01",

abilityName:"UIAbilityApp04Ability",

parameters:{

result:"来自OtherAbility的问候"

}

}

}

在如下代码中要求带结果中断当前的UIAbility:

context.terminateSelfWithResult(abilityResult,(err)=>{

if(err.code){

console.log('出现错误')

}

})

})

运行执行情况如下图所示:

图2 运行执行情况

相关推荐
寒季6666 小时前
Electron 实战:构建跨平台桌面端 Markdown 编辑器(含实时预览、文件操作、快捷键)
华为·electron·harmonyos
峰顶听歌的鲸鱼7 小时前
Kubernetes介绍和部署
运维·笔记·云原生·容器·kubernetes·学习方法
魔芋红茶8 小时前
Spring Security 学习笔记 2:架构
笔记·学习·spring
Lips6119 小时前
2026.1.20力扣刷题笔记
笔记·算法·leetcode
夜雨声烦丿9 小时前
Flutter 框架跨平台鸿蒙开发 - 思维导图开发教程
flutter·华为·harmonyos
Hammer_Hans9 小时前
DFT笔记20
笔记
jane_xing10 小时前
【Hello-Agents】学习笔记(一)
笔记·ai agent
小白阿龙10 小时前
鸿蒙+Flutter 跨平台开发——一款“随机宝盒“的开发流程
flutter·华为·harmonyos·鸿蒙
小雨青年11 小时前
鸿蒙 HarmonyOS 6 | 逻辑核心 (05):数据持久化 Preferences 的封装最佳实践
华为·harmonyos
哈哈你是真的厉害11 小时前
基础入门 React Native 鸿蒙跨平台开发:多种Switch 开关介绍
react native·react.js·harmonyos