Harmony Next - 组件的生命周期

177 阅读4分钟

前言

在日常开发中,经常会有一些需求需要在特定的时间去做,比如页面加载之前获取网络数据、页面消失的时候取消定时器或者应用退到后台之后继续某些计算任务等等。

这些情况下,我们需要去适当的生命周期函数中去做相应的逻辑。在鸿蒙系统中,其有生命周期函数的主要包括以下几大类:

  • UIAbility 组件
  • 自定义组件和页面
  • 通用组件
  • NavDestination 组件

下面通过代码来实际看一下这几类的生命周期函数。

UIAbility 组件

UIAbility的生命周期包括以下四个函数:

  • onCreate:应用加载过程中,UIAbility 实例创建完成时调用,在这里可以对页面需要的数据进行处理。
  • onForeground:UIAbility 实例切换到前台时调用,在这里可以申请系统需要的资源。
  • onBackground:UIAbility 实例切换到后台时调用,在这里可以释放释放资源。
  • onDestroy:UIAbility 实例销毁时触发,在这里也可以进行资源释放。

示例代码如下:

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    hilog.info(0x0000, 'testTag', '%{public}s', '调用 Ability 的 onCreate 函数');
  }

  onDestroy(): void {
    hilog.info(0x0000, 'testTag', '%{public}s', '调用 Ability 的 onDestroy 函数');
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', '调用 Ability 的 onWindowStageCreate 函数');

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

  onWindowStageWillDestroy(windowStage: window.WindowStage): void {
    hilog.info(0x0000, 'testTag', '%{public}s', '调用 Ability 的 onWindowStageWillDestroy 函数');
  }

  onWindowStageRestore(windowStage: window.WindowStage): void {
    hilog.info(0x0000, 'testTag', '%{public}s', '调用 Ability 的 onWindowStageRestore 函数');
  }

  onWindowStageDestroy(): void {
    // Main window is destroyed, release UI related resources
    hilog.info(0x0000, 'testTag', '%{public}s', '调用 Ability 的 onWindowStageDestroy 函数');
  }

  onForeground(): void {
    // Ability has brought to foreground
    hilog.info(0x0000, 'testTag', '%{public}s', '调用 Ability 的 onForeground 函数');
  }

  onBackground(): void {
    // Ability has back to background
    hilog.info(0x0000, 'testTag', '%{public}s', '调用 Ability 的 onBackground 函数');
  }
}

看完上面的代码我们可以发现,有这四个函数是不在 UIAbility 的生命周期里的。实际上,UIAbility 实例创建完成之后,在 onForeground 函数之前系统会创建一个 WindowStage 实例,该实例创建完之后会进入onWindowStageCreate 回调,在这个回调中会加载首页。

关于 WindowStage 的生命周期函数有下面四个:

  • onWindowStageCreate:onCreate 之后,onForeground 之前调用。
  • onWindowStageRestore:当迁移多实例ability时,恢复WindowStage后调用。
  • onWindowStageWillDestroy:当WindowStage即将销毁时调用。
  • onWindowStageDestroy:当WindowStage销毁后调用。

总体的生命周期函数顺序图如下:

image.png

自定义组件和页面

在鸿蒙中,自定义组件代表的是我们用 @Component@ComponentV2 修饰的 UI 基本单元元素;而页面是由 @Entry 修饰的,一个页面只能有一个 @Entry 修饰。它俩的关系类似于 UIView 和 UIViewController 的关系。

页面的生命周期函数有以下三个:

  • onPageShow:页面显示时触发,包括路由过程、应用进入前台等场景。
  • onPageHide:页面隐藏时触发,包括路由过程、应用进入后台等场景。
  • onBackPress:当用户点击返回按钮时触发。

组件的生命周期函数也有三个:

  • aboutToAppear:组件即将出现时回调该接口,在执行其build()函数之前执行。
  • onDidBuild:组件build()函数执行完成之后回调该接口,不建议在onDidBuild函数中更改状态变量、使用animateTo等功能,这可能会导致不稳定的UI表现。
  • aboutToDisappear:定义组件析构销毁之前执行。注意不要在 aboutToDisappear 函数中改变状态变量,特别是 @Link 变量的修改可能会导致应用程序行为不稳定。

示例代码如下:

@Entry
@Component
struct Index {
  build() {
    NavDestination() {
      Column() {
        Image($r('app.media.view'))
      }
      .backgroundColor(Color.Red)
      .width('100%')
      .height('100%')
    }
  }
  // 自定义组件的生命周期函数
  aboutToAppear(): void {
    console.log("调用了 aboutToAppear");
  }

  onDidBuild(): void {
    console.log("调用了 onDidBuild");
  }

  aboutToDisappear(): void {
    console.log("调用了 aboutToDisappear");
  }

  // 页面的生命周期函数
  onPageShow(): void {
    console.log("调用了 onPageShow");
  }

  onPageHide(): void {
    console.log("调用了 onPageHide");
  }

  onBackPress(): boolean | void {
    console.log("调用了 onBackPress");
  }
}

生命周期函数顺序图如下:

image.png

通用组件

通用组件的生命周期函数一共有下面四个:

  • onAttach:组件挂载至组件树时触发此回调。
  • onDetach:组件从组件树卸载时触发此回调。
  • OnAppear:组件挂载显示后触发此回调。
  • onDisAppear:组件卸载消失时触发此回调。

示例代码如下:

Column(){
  Text("PageOne");
}
.onAttach(() => {
  console.log("调用了 onAttach");
})
.onAppear(() => {
  console.log("调用了 onAppear");
})
.onDisAppear(() => {
  console.log("调用了 onDisAppear");
})
.onDetach(() => {
  console.log("调用了 onDetach");
})

这四个函数是任意组件都会调用的,包括后面要介绍的 NavDestination 组件。

NavDestination 组件

NavDestination 是 Navigation 组件的组件,它特有的生命周期函数一共有以下七个:

  • onWillAppear:当该Destination挂载之前触发。
  • onWillShow:当该Destination显示之前触发。
  • onShow:当该NavDestination页面显示时触发。
  • onWillHide:当该Destination隐藏之前触发。
  • onHidden:当该NavDestination页面隐藏时触发。
  • onWillDisappear:当该Destination卸载之前触发。
  • onReady:当NavDestination即将构建子组件之前会触发。

示例代码如下:

@Component
struct PageOne {
  pathStack: NavPathStack = new NavPathStack()

  build() {
    NavDestination() {
      Column(){
        Text("PageOne");
      }
    }
    .title('PageOne')
    .onWillAppear(() => {
      console.log("调用了 onWillAppear");
    })
    .onWillShow(() => {
      console.log("调用了 onWillShow");
    })
    .onShown(() => {
      console.log("调用了 onShown");
    })
    .onWillHide(() => {
      console.log("调用了 onWillHide");
    })
    .onHidden(() => {
      console.log("调用了 onHidden");
    })
    .onWillDisappear(() => {
      console.log("调用了 onWillDisappear");
    })
    .onReady((context: NavDestinationContext) => {
      console.log("调用了 onReady");
    })
  }
}