生命周期

  • NavDestination生命周期
    • onWillAppear
    • onAppear
    • onWillShow
    • onShown
    • onWillHide
    • onHidden
    • onWillDisappear
    • onDisAppear
    • onBackPress
组件-生命周期

生命周期-官网链接

  • 自定义组件:@Component装饰的UI单元,可以组合多个系统组件实现UI的复用。
  • 页面:即应用的UI页面。可以由一个或者多个自定义组件组成,@Entry装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个@Entry。只有被@Entry装饰的组件才可以调用页面的生命周期。
  • 带@Entry修饰符的组件
页面生命周期,即被@Entry装饰的组件生命周期,提供以下生命周期接口:
● onPageShow:页面每次显示时触发。
● onPageHide:页面每次隐藏时触发一次。
● onBackPress:当用户点击返回按钮时触发。
  • 自定义组件生命周期
组件生命周期,即一般用@Component装饰的自定义组件的生命周期,提供以下生命周期接口:
aboutToAppear:组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build()函数之前执行。
aboutToDisappear:在自定义组件即将析构销毁时执行。
  • 因为@Entry 也是@Component组件,所以页面组件同时拥有自定义组件的生命周期

  • 修饰符Reusable, 复用组件的情况多一个 , aboutToReuse => 当我们的组件被Reusable修饰符修饰的时候,组件被复用的时候,会触发该逻辑, 一般在这里面取到原有参数,根据自身的业务对数据进行重置
  • abouteToAppear => build => onPageShow
  • onPageHide => aboutToDisappear
  • 所有的系统组件都有onAppear和onDisAppear事件
  • 所有的自定义组件都有aboutToAppear 和aboutToDisappear
  • 在组件中测试一下
aboutToAppear() {
    console.log("页面初始化")
  }
  onPageShow() {
    console.log("页面显示")
  }
  onPageHide() {
    console.log("页面隐藏")
  }
  aboutToDisAppear() {
    // 清理定时器
    console.log("页面销毁")
  }
  onBackPress() {
    console.log("后退键")
  }
  • 更多的逻辑会在aboutToAppear中做数据加载
  • onPageShow也可以做数据加载 分场景
  • 生活场景下- 送菜送外卖的网约车 具有时效性的业务 需要在onPageShow
  • 偏固定性场景获取一次数据就行
  • aboutToDisAppear
  • 清理定时任务 。清理监听-线程监听-进程监听

  • 带@Entry的页面组件 拥有页面进入,页面销毁,页面显示,页面隐藏, 页面返回的生命周期
  • @Component自定义组件 拥有 组件进入、组件销毁生命周期
  • 在返回页面中,可以进行处理控制是否返回
  • 在onBackPress中
    • return true 表示阻止返回 => 用户想要自己控制返回
    • return false 表示允许返回 => 使用系统的返回
  • 在返回时控制返回
 onBackPress() {
    promptAction.showDialog({
      message: '确定要退出吗',
      buttons: [{
        text: '取消',
        color: "black"
      },{
        text: '确定',
        color: "black"
      }],
    })
    .then((result) => {
      if(result.index === 1) {
        router.back()
      }

    })
    return true
  }
  • 因为没有办法在生命周期中实现async和await,所以先手动让页面不返回,然后再确定是否要返回,如果确定要返回,就用router.back来实现

2. UIAbility-生命周期

UIAbility-生命周期

UIAbility的生命周期包括Create、Foreground、Background、Destroy四个状态,如下图所示。

  • onCreate(实例创建)

Ability创建时回调,执行初始化业务逻辑操作。

  • onDestory

Ability生命周期回调,在销毁时回调,执行资源清理等操作。

  • onWindowStageCreate

当WindowStage创建后调用。

  • onWindowStageDestory

当WindowStage销毁后调用。

  • onForeground

Ability生命周期回调,当应用从后台转到前台时触发。

  • onBackground

Ability生命周期回调,当应用从前台转到后台时触发

  • onNewWant(会在打开一个新的任务窗口,但是该任务窗口已经存在的情况下)/
  • 单例模式下会执行onNewWant,多例模式
  • UIAbility相当于我们应用中的一个任务,我们可以把自己的app想象成一个UIAbility,但是当项目越来越大,需要扩展和分担业务的时候,可以采取多个UIAbility

3. Ability跳转

  • 多个的abiltiy必须建立在hap中
  • hsp和har均不让建ability

:::color1
Stage模型-FA模型

  • 模块-hap-hsp -har
  • UIAbility- 项目中默认有一个- 任务窗口-绘制页面
  • Page
  • Component

比如微信- 聊天-支付

:::

:::color1

  • UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口;
  • 一个UIAbility组件中可以通过多个页面来实现一个功能模块;
  • 每一个UIAbility组件实例,都对应于一个最近任务列表中的任务。

当我们项目中拆解多个任务的时候,可以通过新建多个Ability的方式来进行任务的拆解

  • 比如,我们支付的之后想新开一个任务去专门处理这件事,就可以采用拉起一个新的Ability来实现

:::

  • 新建一个支付Ablility - PayAbility

  • 新建PayAbility对应的跳转的支付页面 PayIndex.ets
@Entry
@Component
struct PayIndex {

  build() {
    Row() {
      Column({ space: 15 }) {
        Text("支付Ability")
          .fontSize(40)
          .fontColor(Color.Red)
        Button("支付")
          .width('100%')
      }

    }
    .height('100%')
    .padding(20)
  }
}

  • 新建一个主页Page- MainPage用来跳转到支付Ability
@Entry
@Component
struct MainPage {

  build() {
    Row() {
      Column({ space: 15 }){
        Text("主Ability")
          .fontSize(50)
        Button("去支付")
          .width('100%')
      }

    }
    .height('100%')
    .padding(20)
  }
}

:::info

  • ability的拉起必须通过模拟器-所以把我们主Ability的启动页设置为我们刚刚新建的主页

:::

:::info
接下来,我们点击去支付按钮的时候 要拉起支付PayAbility

我们采用当前Ability的上下文来实现,使用文档链接

:::

  • 使用Context上下文拉起Ability

:::info
这里我们需要准备一个参数Want

:::

let want: Want = {
      'deviceId': '', // deviceId为空表示本设备
      'bundleName': '包名',
      'abilityName': 'abilityName',
  };
  • 拉起Ability
 let want: Want = {
              'deviceId': '', // deviceId为空表示本设备
              'bundleName': 'com.itheima.studu_case',
              'abilityName': 'PayAbility',
            };
            (getContext() as common.UIAbilityContext)
              .startAbility(want)

:::success
假设我们想调用第三方的包可不可以?

回答: 当然可以,我们只需要知道第三方的包名即可

:::

:::color2
接下来,我们需要传递参数了

  • 我们需要拉起Ability的时候,传过去一个订单id,让支付能够拿到这个id进行支付相关的事宜
  • 传参使用parameters,它是一个object类型,你可以传递你想传的任意数据

:::

  • Ablility传参数

  • 在HeimaPay中的HeimaPayAbility使用AppStorage进行接收并设置
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    AppStorage.setOrCreate<number>("order_id", want.parameters!["order_id"] as number)
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  }
  onNewWant(want: Want) {
    const params =  want.parameters as AbilityParams
    AppStorage.Set<number>("order_id", params.order_id)

  }

:::info
onNewWant表示当前的PayAbility并未销毁的情况下 会调用

:::

  • 在PayIndex中使用StoreageProp接受
  @StorageProp('order_id')
  orderId: number = 0

  • 执行完副Ability并返回结果
  Button("支付")
          .width('100%')
          .onClick(() => {
            const context =  getContext(this) as common.UIAbilityContext
            context.terminateSelfWithResult({
              resultCode: 1,
              want: {
                abilityName: 'EntryAbility',
                bundleName: 'com.itheima.harmonybase',
                parameters: {
                  paySuccess: true
                }
              }
            })
          })

:::info
值得注意的是:如果我们想要获取副Ability对应的结果,在startAbility的时候需要使用startAbilityForResult来实现

:::

 const result =  await (getContext(this) as common.UIAbilityContext).startAbilityForResult({
                'bundleName': 'com.itheima.harmonybase',
                'abilityName': 'PayAbility',
                parameters: {
                  order_id: Date.now()
                }
              })
              AlertDialog.show({
                message: JSON.stringify(result)
              })

:::info
我们可以根据支付结果进行数据和业务的处理

:::

:::color2
定义返回参数的类型

:::

type ResultParams = Record<string, boolean>

  • 接收Ability的返回结果
type ResultParams = Record<string, boolean>
const result =  await (getContext(this) as common.UIAbilityContext).startAbilityForResult({
                'bundleName': 'com.itheima.harmonybase',
                'abilityName': 'PayAbility',
                parameters: {
                  order_id: Date.now()
                }
              })
              const params =  result.want?.parameters as ResultParams

              if(params.paySuccess) {
                promptAction.showToast({ message: '支付成功' })
              }else {
                promptAction.showToast({ message: '支付失败' })
              }

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐