应用内启动UIAbility

应用内启动UIAbility

上篇介绍了UIAbility生命周期,这篇学习下UIAbility页面间的跳转。UIAbility对照Android中的Activity,在Android启动其他页面可以通过startActivity(),在Harmony中也有类似的方法startAbility()

UIAbility页面的跳转主要涉及两个场景:

其一,应用内各个UIAbility之间的切换

其二,不同应用间的UIAbility跳转

这里需要先介绍下Context上下文,Context是应用中对象的上下文,其提供了应用的一些基础信息。例如 resourceManager(资源管理)、applicationInfo(当前应用信息)、dir(应用文件路径)、area(文件分区)等,以及应用的一些基本方法,例如 createBundleContext()、getApplicationContext()等。

该类的作用和Android中的Context类似,在Android中Activity是继承了Context的,所以是可以直接调用startActivity
但是在Harmony页面组件中需要通过getContext(this) as common.UIAbilityContext获取到UIAbilityContext再调用startAbility()进行页面跳转。

在Android中startActivity需要传入Intent指定跳转的目标页面,在Harmony中也对应的的类来实现,这就是信息传递载体WantWant是Harmony中系统组件间通讯的重要信息载体。

  • bundleName 应用包名

  • abilityName 跳转的UIAbility名称

  • deviceId 表示目标Ability所在设备ID。如果未设置该字段,则表明本设备。

  • uri 表示携带的数据,一般配合type使用,指明待处理的数据类型。如果在Want中指定了uri,则Want将匹配指定的Uri信息,包括scheme, schemeSpecificPart, authority和path信息。

  • type 表示携带数据类型,使用MIME类型规范。例如:"text/plain"、"image/*"等。

  • flags 表示处理Want的方式。例如通过wantConstant.Flags.FLAG_ABILITY_CONTINUATION表示是否以设备间迁移方式启动Ability。

  • action 表示要执行的通用操作(如分享,打开浏览器等)。

  • parammeters 传递的参数

  • entities 将调用方传入的want参数的entities与待匹配应用组件的skills配置中的entities进行匹配。

  • moduleName 表示目标Ability所属的模块名称。

下面针对一些使用场景分别介绍下跳转的接口。

应用内跳转

简单页面切换

使用方法

startAbility(want: Want, options?: StartOptions): Promise;

调用示例

let context = getContext(this) as common.UIAbilityContext;
let want: Want = {
  bundleName: 'com.byrain.example_001',
  abilityName: 'TargetAbility'
}
context.startAbility(want)
.then(() => {
  hilog.info(0x0000, 'testTag', '%{public}s', '登录成功');
})
.catch((err: BusinessError) => {
  // 错误码 参考 https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V14/js-apis-inner-application-uiabilitycontext-V14#uiabilitycontextstartability-2
  hilog.error(0x0000, 'testTag', `startAbility failed, code is ${err.code}, message is ${err.message}`);
});

携带参数跳转页面

使用方法

startAbility(want: Want, options?: StartOptions): Promise;

调用示例

let context = getContext(this) as common.UIAbilityContext;
let want: Want = {
  bundleName: 'com.byrain.example_001',
  abilityName: 'TargetAbility',
  parameters: {
    text: '这是传递的参数'
  }
}
context.startAbility(want)
  .then(() => {
    hilog.info(0x0000, 'testTag', '%{public}s', '登录成功');
  })
  .catch((err: BusinessError) => {
    // 错误码 参考 https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V14/js-apis-inner-application-uiabilitycontext-V14#uiabilitycontextstartability-2
    hilog.error(0x0000, 'testTag', `startAbility failed, code is ${err.code}, message is ${err.message}`);
  });

参数传递必然需要接收,在TargetAbiilty的onCreate生命周期回调中可以通过参数want:Want获取到,另外也可以在UIAbility中通过this.launchWant直接使用Want.

export default class TargetAbility extends UIAbility {

 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
  if (want.parameters) {
    hilog.info(DOMAIN, 'testTag', '%{public}s', want.parameters.text);
  }
  if (this.launchWant.parameters) {
    hilog.info(DOMAIN, 'testTag', '%{public}s', this.launchWant.parameters.text);
  }
}
......

我们启动程序查看下日志,实验成功。

02-24 17:13:16.107   13395-13395   A00000/testTag          I     Ability onCreate
02-24 17:13:16.126   13395-13395   A00000/testTag          I     Ability onWindowStageCreate
02-24 17:13:16.150   13395-13395   A00000/testTag          I     Ability onForeground
02-24 17:13:16.206   13395-13395   A00000/testTag          I     Succeeded in loading the content.
02-24 17:13:21.661   13395-13395   A00000/testTag          I     登录成功
02-24 17:13:21.684   13395-13395   A00000/testTag          I     Ability onBackground
02-24 17:13:21.692   13395-13395   A00000/testTag          I     Ability onCreate
02-24 17:13:21.692   13395-13395   A00000/testTag          I     这是传递的参数
02-24 17:13:21.692   13395-13395   A00000/testTag          I     这是传递的参数
02-24 17:13:21.708   13395-13395   A00000/testTag          I     Ability onWindowStageCreate
02-24 17:13:21.713   13395-13395   A00000/testTag          I     Ability onForeground
02-24 17:13:21.738   13395-13395   A00000/testTag          I     Succeeded in loading the content.

跳转页面并获取返回值

在Android中我们启动页面获取结果使用startActivityForResult,同时还需要在目标页面调用setResult设置返回结果。HarmonyOS中想要获取返回值需要使用如下方法

startAbilityForResult(want: Want, options?: StartOptions): Promise;

同样在目标页面中需要调用如下函数来返回参数,这样调用方的UIAbility即可在回调中获取响应的结果。

terminateSelfWithResult(parameter: AbilityResult): Promise;

调用示例

启动页面调用

const RESULT_CODE:number = 1001
let context = getContext(this) as common.UIAbilityContext;

let want: Want = {
  bundleName: 'com.byrain.example_001',
  abilityName: 'TargetAbility'
}
context.startAbilityForResult(want)
  .then((data) => {
    if (data.resultCode === RESULT_CODE) {
      hilog.info(0x0000, 'testTag', '目标页面返回结果: %{public}s', JSON.stringify(data?.want?.parameters) ?? '响应参数异常');
    }
  })
  .catch((err: BusinessError) => {
    hilog.error(0x0000, 'testTag', `startAbilityForResult failed, code is ${err.code}, message is ${err.message}`);
  });

响应页面返回

let context = getContext(this) as common.UIAbilityContext
let result : common.AbilityResult = {
  resultCode: RESULT_CODE,
  want: {
    parameters: {
      response: '这是返回的响应信息'
    }
  }
}
context.terminateSelfWithResult(result, (err)=> {
  if (err.code) {
    hilog.error(0x0000, 'testTag', `terminateSelfWithResult failed, code is ${err.code}, message is ${err.message}`);
  }
})

请求方在处理返回结果时候判断的RESULT_CODE必须和目标页面返回指定的一致

我们看下页面调用日志

02-25 10:31:35.859   6666-6666     A00000/testTag                  pid-6666              I     Ability onCreate
02-25 10:31:35.881   6666-6666     A00000/testTag                  pid-6666              I     Ability onWindowStageCreate
02-25 10:31:35.919   6666-6666     A00000/testTag                  pid-6666              I     Ability onForeground
02-25 10:31:35.981   6666-6666     A00000/testTag                  pid-6666              I     Succeeded in loading the content.
02-25 10:31:39.956   6666-6666     A00000/testTag                  com.byrai...mple_001  I     Ability onBackground
02-25 10:31:39.967   6666-6666     A00000/testTag                  com.byrai...mple_001  I     Ability onCreate
02-25 10:31:39.976   6666-6666     A00000/testTag                  com.byrai...mple_001  I     Ability onWindowStageCreate
02-25 10:31:39.986   6666-6666     A00000/testTag                  com.byrai...mple_001  I     Ability onForeground
02-25 10:31:40.017   6666-6666     A00000/testTag                  com.byrai...mple_001  I     Succeeded in loading the content.
02-25 10:31:41.102   6666-6666     A00000/testTag                  com.byrai...mple_001  I     Ability onForeground
02-25 10:31:41.119   6666-6666     A00000/testTag                  com.byrai...mple_001  I     目标页面返回结果: {"moduleName":"","response":"这是返回的响应信息"}
02-25 10:31:41.120   6666-6666     A00000/testTag                  com.byrai...mple_001  I     Ability onBackground
02-25 10:31:41.130   6666-6666     A00000/testTag                  com.byrai...mple_001  I     Ability onWindowStageDestroy
02-25 10:31:41.130   6666-6666     A00000/testTag                  com.byrai...mple_001  I     Ability onDestroy

很明显,当我们调用terminateSelfWithResult返回结果时候目标页面实例会被彻底销毁,这个不同与返回按钮,单纯按返回按钮目标页面仅仅退回到后台并没有销毁。

posted @ 2025-03-06 14:53  拜雨  阅读(114)  评论(0)    收藏  举报