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 运行执行情况

相关推荐
li星野5 小时前
打工人日报#20251231
笔记
孙严Pay5 小时前
分享三种不同的支付体验,各自有着不同的特点与适用场景。
笔记·科技·计算机网络·其他·微信
YJlio5 小时前
VolumeID 学习笔记(13.10):卷序列号修改与资产标识管理实战
windows·笔记·学习
weixin_440730505 小时前
java数组整理笔记
java·开发语言·笔记
小龙5 小时前
【学习笔记】多标签交叉熵损失的原理
笔记·学习·多标签交叉熵损失
wangxiaowu19867 小时前
HarmonyOS NEXT和通用JSBridge
华为·harmonyos
强子感冒了8 小时前
Java学习笔记:String、StringBuilder与StringBuffer
java·开发语言·笔记·学习
不会学习?9 小时前
大二元旦,2025最后一天
经验分享·笔记
NULL指向我10 小时前
STM32F407VET6学习笔记14:Bootloader程序笔记
笔记·stm32·学习
伶星3710 小时前
obsidian 日记按年月存放
笔记