HarmonyOS学习——UIAbility组件(下)
UIAbility内的页面创建
UIAbility组件基本用法
指定UIAbility的启动页面
根据需要将index页面路径替换为MyPage
应用中的UIAbility在启动过程中,需要指定启动页面,否则应用启动后会因为没有默认加载页面而导致白屏。可以在UIAbility的onWindowStageCreate()生命周期回调中,通过WindowStage对象的loadContent()方法设置启动页面。
import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';export default class EntryAbility extends UIAbility {onWindowStageCreate(windowStage: window.WindowStage): void {// Main window is created, set main page for this abilitywindowStage.loadContent('pages/Index', (err, data) => {// ...});}// ...
}
说明
在DevEco Studio中创建的UIAbility中,该UIAbility实例默认会加载Index页面,根据需要将Index页面路径替换为需要的页面路径即可。
获取UIAbility的上下文信息
UIAbility类拥有自身的上下文信息,该信息为UIAbilityContext类的实例,UIAbilityContext类拥有abilityInfo、currentHapModuleInfo等属性。通过UIAbilityContext可以获取UIAbility的相关配置信息,如包代码路径、Bundle名称、Ability名称和应用程序需要的环境状态等属性信息,以及可以获取操作UIAbility实例的方法(如startAbility()、connectServiceExtensionAbility()、terminateSelf()等)。
如果需要在页面中获得当前Ability的Context,可调用getContext接口获取当前页面关联的UIAbilityContext或ExtensionContext。
-
在UIAbility中可以通过this.context获取UIAbility实例的上下文信息。
-
import { UIAbility, AbilityConstant, Want } from '@kit.AbilityKit';export default class EntryAbility extends UIAbility {onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {// 获取UIAbility实例的上下文let context = this.context;// ...} }
在页面中获取UIAbility实例的上下文信息,包括导入依赖资源context模块和在组件中定义一个context变量两个部分。
-
import { common, Want } from '@kit.AbilityKit';@Entry @Component struct Page_EventHub {private context = getContext(this) as common.UIAbilityContext;startAbilityTest(): void {let want: Want = {// Want参数信息};this.context.startAbility(want);}// 页面展示build() {// ...} }
也可以在导入依赖资源context模块后,在具体使用UIAbilityContext前进行变量定义。
-
import { common, Want } from '@kit.AbilityKit';@Entry @Component struct Page_UIAbilityComponentsBasicUsage {startAbilityTest(): void {let context = getContext(this) as common.UIAbilityContext;let want: Want = {// Want参数信息};context.startAbility(want);}// 页面展示build() {// ...} }
当业务完成后,开发者如果想要终止当前UIAbility实例,可以通过调用terminateSelf()方法实现。
-
import { common } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit';@Entry @Component struct Page_UIAbilityComponentsBasicUsage {// 页面展示build() {Column() {//...Button('FuncAbilityB').onClick(() => {let context = getContext(this) as common.UIAbilityContext;try {context.terminateSelf((err: BusinessError) => {if (err.code) {// 处理业务逻辑错误console.error(`terminateSelf failed, code is ${err.code}, message is ${err.message}`);return;}// 执行正常业务console.info('terminateSelf succeed');});} catch (err) {// 捕获同步的参数错误let code = (err as BusinessError).code;let message = (err as BusinessError).message;console.error(`terminateSelf failed, code is ${code}, message is ${message}`);}})}} }
UIAbility组件与UI的数据同步
基于当前的应用模型,可以通过以下几种方式来实现UIAbility组件与UI之间的数据同步。
- 使用EventHub进行数据通信:在基类Context中提供了EventHub对象,可以通过发布订阅方式来实现事件的传递。在事件传递前,订阅者需要先进行订阅,当发布者发布事件时,订阅者将接收到事件并进行相应处理。
- 使用AppStorage/LocalStorage进行数据同步:ArkUI提供了AppStorage和LocalStorage两种应用级别的状态管理方案,可用于实现应用级别和UIAbility级别的数据同步。
使用EventHub进行数据通信
EventHub为UIAbility组件提供了事件机制,使它们能够进行订阅、取消订阅和触发事件等数据通信能力。
在基类Context中,提供了EventHub对象,可用于在UIAbility组件实例内通信。使用EventHub实现UIAbility与UI之间的数据通信需要先获取EventHub对象,本章节将以此为例进行说明。
-
1、在UIAbility中调用eventHub.on()方法注册一个自定义事件“event1”,eventHub.on()有如下两种调用方式,使用其中一种即可。
import { hilog } from '@kit.PerformanceAnalysisKit';
import { UIAbility, Context, Want, AbilityConstant } from '@kit.AbilityKit';const DOMAIN_NUMBER: number = 0xFF00;
const TAG: string = '[EventAbility]';export default class EntryAbility extends UIAbility {onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {// 获取eventHublet eventhub = this.context.eventHub;// 执行订阅操作eventhub.on('event1', this.eventFunc);eventhub.on('event1', (data: string) => {// 触发事件,完成相应的业务操作});hilog.info(DOMAIN_NUMBER, TAG, '%{public}s', 'Ability onCreate');}// ...eventFunc(argOne: Context, argTwo: Context): void {hilog.info(DOMAIN_NUMBER, TAG, '1. ' + `${argOne}, ${argTwo}`);return;}
}
2、在UI中通过eventHub.emit()方法触发该事件,在触发事件的同时,根据需要传入参数信息。
import { common } from '@kit.AbilityKit';
import { promptAction } from '@kit.ArkUI';@Entry
@Component
struct Page_EventHub {private context = getContext(this) as common.UIAbilityContext;eventHubFunc(): void {// 不带参数触发自定义“event1”事件this.context.eventHub.emit('event1');// 带1个参数触发自定义“event1”事件this.context.eventHub.emit('event1', 1);// 带2个参数触发自定义“event1”事件this.context.eventHub.emit('event1', 2, 'test');// 开发者可以根据实际的业务场景设计事件传递的参数}build() {Column() {// ...List({ initialIndex: 0 }) {ListItem() {Row() {// ...}.onClick(() => {this.eventHubFunc();promptAction.showToast({message: 'EventHubFuncA'});})}// ...ListItem() {Row() {// ...}.onClick(() => {this.context.eventHub.off('event1');promptAction.showToast({message: 'EventHubFuncB'});})}// ...}// ...}// ...}
}
3、在UIAbility的注册事件回调中可以得到对应的触发事件结果,运行日志结果如下所示。
[Example].[Entry].[EntryAbility] 1. []
[Example].[Entry].[EntryAbility] 1. [1]
[Example].[Entry].[EntryAbility] 1. [2,"test"]
4、在自定义事件“event1”使用完成后,可以根据需要调用eventHub.off()方法取消该事件的订阅。
import { UIAbility } from '@kit.AbilityKit';export default class EntryAbility extends UIAbility {// ... onDestroy(): void {this.context.eventHub.off('event1');}
}
使用AppStorage/LocalStorage进行数据同步
ArkUI提供了AppStorage和LocalStorage两种应用级别的状态管理方案,可用于实现应用级别和UIAbility级别的数据同步。使用这些方案可以方便地管理应用状态,提高应用性能和用户体验。其中,AppStorage是一个全局的状态管理器,适用于多个UIAbility共享同一状态数据的情况;而LocalStorage则是一个局部的状态管理器,适用于单个UIAbility内部使用的状态数据。通过这两种方案,开发者可以更加灵活地控制应用状态,提高应用的可维护性和可扩展性。详细请参见应用级变量的状态管理。
UIAbility组件间交互(设备内)
启动应用内的UIAbility
当一个应用内包含多个UIAbility时,存在应用内启动UIAbility的场景。例如在支付应用中从入口UIAbility启动收付款UIAbility。
假设应用中有两个UIAbility:EntryAbility和FuncAbility(可以在同一个Module中,也可以在不同的Module中),需要从EntryAbility的页面中启动FuncAbility。
-
1、在EntryAbility中,通过调用startAbility()方法启动UIAbility,want为UIAbility实例启动的入口参数,其中bundleName为待启动应用的Bundle名称,abilityName为待启动的Ability名称,moduleName在待启动的UIAbility属于不同的Module时添加,parameters为自定义信息参数。示例中的context的获取方式请参见获取UIAbility的上下文信息。
import { common, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';const TAG: string = '[Page_UIAbilityComponentsInteractive]';
const DOMAIN_NUMBER: number = 0xFF00;@Entry
@Component
struct Page_UIAbilityComponentsInteractive {private context = getContext(this) as common.UIAbilityContext;build() {Column() {//...List({ initialIndex: 0 }) {ListItem() {Row() {//...}.onClick(() => {// context为Ability对象的成员,在非Ability对象内部调用需要// 将Context对象传递过去let wantInfo: Want = {deviceId: '', // deviceId为空表示本设备bundleName: 'com.samples.stagemodelabilitydevelop',moduleName: 'entry', // moduleName非必选abilityName: 'FuncAbilityA',parameters: {// 自定义信息info: '来自EntryAbility Page_UIAbilityComponentsInteractive页面'},};// context为调用方UIAbility的UIAbilityContextthis.context.startAbility(wantInfo).then(() => {hilog.info(DOMAIN_NUMBER, TAG, 'startAbility success.');}).catch((error: BusinessError) => {hilog.error(DOMAIN_NUMBER, TAG, 'startAbility failed.');});})}//...}//...}//...}
}
2、在FuncAbility的onCreate()或者onNewWant()生命周期回调文件中接收EntryAbility传递过来的参数。
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';export default class FuncAbilityA extends UIAbility {onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {// 接收调用方UIAbility传过来的参数let funcAbilityWant = want;let info = funcAbilityWant?.parameters?.info;}//...
}
说明
在被拉起的FuncAbility中,可以通过获取传递过来的want参数的parameters来获取拉起方UIAbility的PID、Bundle Name等信息。
3、在FuncAbility业务完成之后,如需要停止当前UIAbility实例,在FuncAbility中通过调用terminateSelf()方法实现。
import { common } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';const TAG: string = '[Page_FromStageModel]';
const DOMAIN_NUMBER: number = 0xFF00;@Entry
@Component
struct Page_FromStageModel {build() {Column() {//...Button('FuncAbilityB').onClick(() => {let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // UIAbilityContext// context为需要停止的UIAbility实例的AbilityContextcontext.terminateSelf((err) => {if (err.code) {hilog.error(DOMAIN_NUMBER, TAG, `Failed to terminate self. Code is ${err.code}, message is ${err.message}`);return;}});})}//...}
}
说明
调用terminateSelf()方法停止当前UIAbility实例时,默认会保留该实例的快照(Snapshot),即在最近任务列表中仍然能查看到该实例对应的任务。如不需要保留该实例的快照,可以在其对应UIAbility的module.json5配置文件中,将abilities标签的removeMissionAfterTerminate字段配置为true。
4、如需要关闭应用所有的UIAbility实例,可以调用ApplicationContext的killAllProcesses()方法实现关闭应用所有的进程。
启动应用内的UIAbility并获取返回结果
在一个EntryAbility启动另外一个FuncAbility时,希望在被启动的FuncAbility完成相关业务后,能将结果返回给调用方。例如在应用中将入口功能和账号登录功能分别设计为两个独立的UIAbility,在账号登录UIAbility中完成登录操作后,需要将登录的结果返回给入口UIAbility。
-
1、在EntryAbility中,调用startAbilityForResult()接口启动FuncAbility,异步回调中的data用于接收FuncAbility停止自身后返回给EntryAbility的信息。示例中的context的获取方式请参见获取UIAbility的上下文信息。
import { common, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { promptAction } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';const TAG: string = '[Page_UIAbilityComponentsInteractive]';
const DOMAIN_NUMBER: number = 0xFF00;@Entry
@Component
struct Page_UIAbilityComponentsInteractive {build() {Column() {//...List({ initialIndex: 0 }) {ListItem() {Row() {//...}.onClick(() => {let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // UIAbilityContextconst RESULT_CODE: number = 1001;let want: Want = {deviceId: '', // deviceId为空表示本设备bundleName: 'com.samples.stagemodelabilitydevelop',moduleName: 'entry', // moduleName非必选abilityName: 'FuncAbilityA',parameters: {// 自定义信息info: '来自EntryAbility UIAbilityComponentsInteractive页面'}};context.startAbilityForResult(want).then((data) => {if (data?.resultCode === RESULT_CODE) {// 解析被调用方UIAbility返回的信息let info = data.want?.parameters?.info;hilog.info(DOMAIN_NUMBER, TAG, JSON.stringify(info) ?? '');if (info !== null) {promptAction.showToast({message: JSON.stringify(info)});}}hilog.info(DOMAIN_NUMBER, TAG, JSON.stringify(data.resultCode) ?? '');}).catch((err: BusinessError) => {hilog.error(DOMAIN_NUMBER, TAG, `Failed to start ability for result. Code is ${err.code}, message is ${err.message}`);});})}//...}//...}//...}
}
2、在FuncAbility停止自身时,需要调用terminateSelfWithResult()方法,入参abilityResult为FuncAbility需要返回给EntryAbility的信息。
import { common } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';const TAG: string = '[Page_FuncAbilityA]';
const DOMAIN_NUMBER: number = 0xFF00;@Entry
@Component
struct Page_FuncAbilityA {build() {Column() {//...List({ initialIndex: 0 }) {ListItem() {Row() {//...}.onClick(() => {let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // UIAbilityContextconst RESULT_CODE: number = 1001;let abilityResult: common.AbilityResult = {resultCode: RESULT_CODE,want: {bundleName: 'com.samples.stagemodelabilitydevelop',moduleName: 'entry', // moduleName非必选abilityName: 'FuncAbilityB',parameters: {info: '来自FuncAbility Index页面'},},};context.terminateSelfWithResult(abilityResult, (err) => {if (err.code) {hilog.error(DOMAIN_NUMBER, TAG, `Failed to terminate self with result. Code is ${err.code}, message is ${err.message}`);return;}});})}//...}//...}//...}
}
3、FuncAbility停止自身后,EntryAbility通过startAbilityForResult()方法回调接收被FuncAbility返回的信息,RESULT_CODE需要与前面的数值保持一致。
import { common, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { promptAction } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';const TAG: string = '[Page_UIAbilityComponentsInteractive]';
const DOMAIN_NUMBER: number = 0xFF00;@Entry
@Component
struct Page_UIAbilityComponentsInteractive {build() {Column() {//...List({ initialIndex: 0 }) {ListItem() {Row() {//...}.onClick(() => {let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // UIAbilityContextconst RESULT_CODE: number = 1001;let want: Want = {deviceId: '', // deviceId为空表示本设备bundleName: 'com.samples.stagemodelabilitydevelop',moduleName: 'entry', // moduleName非必选abilityName: 'FuncAbilityA',parameters: {// 自定义信息info: '来自EntryAbility UIAbilityComponentsInteractive页面'}};context.startAbilityForResult(want).then((data) => {if (data?.resultCode === RESULT_CODE) {// 解析被调用方UIAbility返回的信息let info = data.want?.parameters?.info;hilog.info(DOMAIN_NUMBER, TAG, JSON.stringify(info) ?? '');if (info !== null) {promptAction.showToast({message: JSON.stringify(info)});}}hilog.info(DOMAIN_NUMBER, TAG, JSON.stringify(data.resultCode) ?? '');}).catch((err: BusinessError) => {hilog.error(DOMAIN_NUMBER, TAG, `Failed to start ability for result. Code is ${err.code}, message is ${err.message}`);});})}//...}//...}//...}
}
启动UIAbility的指定页面
概述
一个UIAbility可以对应多个页面,在不同的场景下启动该UIAbility时需要展示不同的页面,例如从一个UIAbility的页面中跳转到另外一个UIAbility时,希望启动目标UIAbility的指定页面。
UIAbility的启动分为两种情况:UIAbility冷启动和UIAbility热启动。
- UIAbility冷启动:指的是UIAbility实例处于完全关闭状态下被启动,这需要完整地加载和初始化UIAbility实例的代码、资源等。
- UIAbility热启动:指的是UIAbility实例已经启动并在前台运行过,由于某些原因切换到后台,再次启动该UIAbility实例,这种情况下可以快速恢复UIAbility实例的状态。
本文主要讲解目标UIAbility冷启动和目标UIAbility热启动两种启动指定页面的场景,以及在讲解启动指定页面之前会讲解到在调用方如何指定启动页面。
调用方UIAbility指定启动页面
调用方UIAbility启动另外一个UIAbility时,通常需要跳转到指定的页面。例如FuncAbility包含两个页面(Index对应首页,Second对应功能A页面),此时需要在传入的want参数中配置指定的页面路径信息,可以通过want中的parameters参数增加一个自定义参数传递页面跳转信息。示例中的context的获取方式请参见获取UIAbility的上下文信息。
import { common, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';const TAG: string = '[Page_UIAbilityComponentsInteractive]';
const DOMAIN_NUMBER: number = 0xFF00;@Entry
@Component
struct Page_UIAbilityComponentsInteractive {build() {Column() {//...List({ initialIndex: 0 }) {ListItem() {Row() {//...}.onClick(() => {let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // UIAbilityContextlet want: Want = {deviceId: '', // deviceId为空表示本设备bundleName: 'com.samples.stagemodelabilityinteraction',moduleName: 'entry', // moduleName非必选abilityName: 'FuncAbility',parameters: { // 自定义参数传递页面信息router: 'funcA'}};// context为调用方UIAbility的UIAbilityContextcontext.startAbility(want).then(() => {hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in starting ability.');}).catch((err: BusinessError) => {hilog.error(DOMAIN_NUMBER, TAG, `Failed to start ability. Code is ${err.code}, message is ${err.message}`);});})}//...}//...}//...}
}
目标UIAbility冷启动
目标UIAbility冷启动时,在目标UIAbility的onCreate()生命周期回调中,接收调用方传过来的参数。然后在目标UIAbility的onWindowStageCreate()生命周期回调中,解析调用方传递过来的want参数,获取到需要加载的页面信息url,传入windowStage.loadContent()方法。
import { AbilityConstant, Want, UIAbility } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window, UIContext } from '@kit.ArkUI';const DOMAIN_NUMBER: number = 0xFF00;
const TAG: string = '[EntryAbility]';export default class EntryAbility extends UIAbility {funcAbilityWant: Want | undefined = undefined;uiContext: UIContext | undefined = undefined;onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {// 接收调用方UIAbility传过来的参数this.funcAbilityWant = want;}onWindowStageCreate(windowStage: window.WindowStage): void {// Main window is created, set main page for this abilityhilog.info(DOMAIN_NUMBER, TAG, '%{public}s', 'Ability onWindowStageCreate');// Main window is created, set main page for this abilitylet url = 'pages/Index';if (this.funcAbilityWant?.parameters?.router && this.funcAbilityWant.parameters.router === 'funcA') {url = 'pages/Page_ColdStartUp';}windowStage.loadContent(url, (err, data) => {// ...});}
}
目标UIAbility热启动
在应用开发中,会遇到目标UIAbility实例之前已经启动过的场景,这时再次启动目标UIAbility时,不会重新走初始化逻辑,只会直接触发onNewWant()生命周期方法。为了实现跳转到指定页面,需要在onNewWant()中解析参数进行处理。
例如短信应用和联系人应用配合使用的场景。
- 用户先打开短信应用,短信应用的UIAbility实例启动,显示短信应用的主页。
- 用户将设备回到桌面界面,短信应用进入后台运行状态。
- 用户打开联系人应用,找到联系人张三。
- 用户点击联系人张三的短信按钮,会重新启动短信应用的UIAbility实例。
- 由于短信应用的UIAbility实例已经启动过了,此时会触发该UIAbility的onNewWant()回调,而不会再走onCreate()和onWindowStageCreate()等初始化逻辑。
图1 目标UIAbility热启动
开发步骤如下所示。
-
1、冷启动短信应用的UIAbility实例时,在onWindowStageCreate()生命周期回调中,通过调用getUIContext()接口获取UI上下文实例UIContext对象。
import { hilog } from '@kit.PerformanceAnalysisKit';
import { Want, UIAbility } from '@kit.AbilityKit';
import { window, UIContext } from '@kit.ArkUI';const DOMAIN_NUMBER: number = 0xFF00;
const TAG: string = '[EntryAbility]';export default class EntryAbility extends UIAbility {funcAbilityWant: Want | undefined = undefined;uiContext: UIContext | undefined = undefined;// ...onWindowStageCreate(windowStage: window.WindowStage): void {// Main window is created, set main page for this abilityhilog.info(DOMAIN_NUMBER, TAG, '%{public}s', 'Ability onWindowStageCreate');let url = 'pages/Index';if (this.funcAbilityWant?.parameters?.router && this.funcAbilityWant.parameters.router === 'funcA') {url = 'pages/Page_ColdStartUp';}windowStage.loadContent(url, (err, data) => {if (err.code) {return;}let windowClass: window.Window;windowStage.getMainWindow((err, data) => {if (err.code) {hilog.error(DOMAIN_NUMBER, TAG, `Failed to obtain the main window. Code is ${err.code}, message is ${err.message}`);return;}windowClass = data;this.uiContext = windowClass.getUIContext();});hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');});}
}
2、在短信应用UIAbility的onNewWant()回调中解析调用方传递过来的want参数,通过调用UIContext中的getRouter()方法获取Router对象,并进行指定页面的跳转。此时再次启动该短信应用的UIAbility实例时,即可跳转到该短信应用的UIAbility实例的指定页面。
import { AbilityConstant, Want, UIAbility } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import type { Router, UIContext } from '@kit.ArkUI';
import type { BusinessError } from '@kit.BasicServicesKit';const DOMAIN_NUMBER: number = 0xFF00;
const TAG: string = '[EntryAbility]';export default class EntryAbility extends UIAbility {funcAbilityWant: Want | undefined = undefined;uiContext: UIContext | undefined = undefined;// ...onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {if (want?.parameters?.router && want.parameters.router === 'funcA') {let funcAUrl = 'pages/Page_HotStartUp';if (this.uiContext) {let router: Router = this.uiContext.getRouter();router.pushUrl({url: funcAUrl}).catch((err: BusinessError) => {hilog.error(DOMAIN_NUMBER, TAG, `Failed to push url. Code is ${err.code}, message is ${err.message}`);});}}}
}
说明
当被调用方UIAbility组件启动模式设置为multiton启动模式时,每次启动都会创建一个新的实例,那么onNewWant()回调就不会被用到。
自定义组件生命周期
自定义组件的生命周期回调函数用于通知用户该自定义组件的生命周期变化,这些回调函数是私有的,在运行时由开发框架在特定的时间进行调用,不能从应用程序中手动调用。
- 允许在生命周期函数中使用Promise和异步回调函数,比如网络资源获取,定时器设置等。
- 不允许在生命周期函数中使用async await。
自定义组件的生命周期包括aboutToAppear、onPageShow、onPageHide、onBackPress、aboutToDisappear五种状态,如图所示:
1)aboutToAppear
aboutToAppear?(): void
aboutToAppear函数在创建自定义组件的新实例后,在执行其build函数之前执行。aboutToAppear不同于onPageShow的地方在于该函数仅会在自定义组件实例创建后执行一次。允许在aboutToAppear函数中改变状态变量,更改将在后续执行build函数中生效。aboutToAppear函数可以用于接收自定义组件实例创建时的状态参数,初始化页面状态变量等。
2)aboutToDisappear
aboutToDisappear?(): void
aboutToDisappear函数在自定义组件析构销毁之前执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定。
3)onPageShow
onPageShow?(): void
页面每次显示时触发一次,包括路由过程、应用进入前后台等场景,仅@Entry修饰的自定义组件生效。
4)onPageHide
onPageHide?(): void
页面每次隐藏时触发一次,包括路由过程、应用进入前后台等场景,仅@Entry修饰的自定义组件生效。
5)onBackPress
onBackPress?(): void
当用户点击返回按钮时触发,仅@Entry修饰的自定义组件生效。返回true表示页面自己处理返回逻辑,不进行页面路由,返回false表示使用默认的路由返回逻辑。不设置返回值按照false处理。