赞
踩
当用户浏览、切换和返回到对应应用的时候,应用中的 UIAbility 实例会在其生命周期的不同状态之间转换。
UIAbility 类提供了很多回调,通过这些回调可以知晓当前 UIAbility 的某个状态已经发生改变:例如 UIAbility 的创建和销毁,或者 UIAbility 发生了前后台的状态切换。
例如从桌面点击图库应用图标,到启动图库应用,应用的状态经过了从创建到前台展示的状态变化。如下图所示,从桌面点击图库应用图标启动应用。
回到桌面,从最近任务列表,切换回到图库应用,应用的状态经过了从后台到前台展示的状态变化。如下图所示,从最近任务列表切换回到图库应用。
在UIAbility的使用过程中,会有多种生命周期状态。掌握UIAbility的生命周期,对于应用的开发非常重要。
UIAbility的生命周期包括Create、Foreground、Background、Destroy四个状态,如下图所示。
Create状态,在UIAbility实例创建时触发,系统会调用onCreate回调。可以在onCreate回调中进行相关初始化操作。
- import UIAbility from '@ohos.app.ability.UIAbility';
- import window from '@ohos.window';
-
- export default class EntryAbility extends UIAbility {
- onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
- // 应用初始化
- ...
- }
- ...
- }
例如,用户打开电池管理应用,在应用加载过程中,在UI页面可见之前,可以在onCreate回调中读取当前系统的电量情况,用于后续的UI页面展示。
UIAbility实例创建完成之后,在进入Foreground之前,系统会创建一个WindowStage。
每一个UIAbility实例都对应持有一个WindowStage实例。WindowStage为本地窗口管理器,用于管理窗口相关的内容,例如与界面相关的获焦/失焦、可见/不可见。
WindowStage创建完成后会进入onWindowStageCreate()回调,可以在该回调中设置UI界面加载、设置WindowStage的事件订阅。
- import UIAbility from '@ohos.app.ability.UIAbility';
- import window from '@ohos.window';
-
- export default class EntryAbility extends UIAbility {
- ...
-
- onWindowStageCreate(windowStage: window.WindowStage) {
- // 设置UI页面加载
- // 设置WindowStage的事件订阅(获焦/失焦、可见/不可见)
- ...
-
- windowStage.loadContent('pages/Index', (err, data) => {
- ...
- });
- }
- ...
- }
例如,用户打开游戏应用,正在打游戏的时候,有一个消息通知,打开消息,消息会以弹窗的形式弹出在游戏应用的上方,此时,游戏应用就从获焦切换到了失焦状态,消息应用切换到了获焦状态。对于消息应用,在onWindowStageCreate回调中,会触发获焦的事件回调,可以进行设置消息应用的背景颜色、高亮等操作。
对应于onWindowStageCreate()回调。在UIAbility实例销毁之前,则会先进入onWindowStageDestroy()回调,可以在该回调中释放UI界面资源。例如,在onWindowStageDestroy()中注销获焦/失焦等WindowStage事件。
- import UIAbility from '@ohos.app.ability.UIAbility';
- import window from '@ohos.window';
-
- export default class EntryAbility extends UIAbility {
- ...
-
- onWindowStageDestroy() {
- // 释放UI页面资源
- ...
- }
- }
Foreground和Background状态,分别在UIAbility切换至前台或者切换至后台时触发。分别对应于onForeground回调和onBackground回调。
onForeground回调,在UIAbility的UI页面可见之前,即UIAbility切换至前台时触发。可以在onForeground回调中申请系统需要的资源,或者重新申请在onBackground中释放的资源。
onBackground回调,在UIAbility的UI页面完全不可见之后,即UIAbility切换至后台时候触发。可以在onBackground回调中释放UI页面不可见时无用的资源,或者在此回调中执行较为耗时的操作,例如状态保存等。
- import UIAbility from '@ohos.app.ability.UIAbility';
- import window from '@ohos.window';
-
- export default class EntryAbility extends UIAbility {
- ...
-
- onForeground() {
- // 申请系统需要的资源,或者重新申请在onBackground中释放的资源
- ...
- }
-
- onBackground() {
- // 释放UI页面不可见时无用的资源,或者在此回调中执行较为耗时的操作
- // 例如状态保存等
- ...
- }
- }
例如,用户打开地图应用查看当前地理位置的时候,假设地图应用已获得用户的定位权限授权。在UI页面显示之前,可以在onForeground回调中打开定位功能,从而获取到当前的位置信息。
当地图应用切换到后台状态,可以在onBackground回调中停止定位功能,以节省系统的资源消耗。
Destroy状态,在UIAbility销毁时触发。可以在onDestroy回调中进行系统资源的释放、数据的保存等操作。
- import UIAbility from '@ohos.app.ability.UIAbility';
- import window from '@ohos.window';
-
- export default class EntryAbility extends UIAbility {
- ...
-
- onDestroy() {
- // 系统资源的释放、数据的保存等
- ...
- }
- }
例如,用户使用应用的程序退出功能,会调用 UIAbilityContext 的 terminalSelf() 方法,从而完成 UIAbility 销毁。或者用户使用最近任务列表关闭该UIAbility实例时,也会完成UIAbility的销毁。
页面,即应用的UI页面。可以由一个或者多个自定义组件组成,@Entry装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个@Entry。
只有被@Entry装饰的组件才可以调用页面的生命周期。
页面生命周期,即被@Entry装饰的组件生命周期,提供以下生命周期接口:
页面也是由入口组件和其他组件构成,所以也包含组件生命周期。
组件生命周期,即一般用@Component装饰的自定义组件的生命周期,提供以下生命周期接口:
生命周期流程如下图所示,下图展示的是被@Entry装饰的组件(首页)生命周期。
根据上面的流程图,从自定义组件的初始创建、重新渲染和删除来详细解释。
当应用在后台启动时,此时应用进程并没有销毁,所以仅需要执行onPageShow。
当事件句柄被触发(比如设置了点击事件,即触发点击事件)改变了状态变量时,或者LocalStorage / AppStorage中的属性更改,并导致绑定的状态变量更改其值时:
如果 if 组件的分支改变,或者 ForEach 循环渲染中数组的个数改变,组件将被删除:
不建议在生命周期aboutToDisappear内使用 async await,如果在生命周期的aboutToDisappear使用异步操作(Promise或者回调方法),自定义组件将被保留在Promise的闭包中,直到回调方法被执行完,这个行为阻止了自定义组件的垃圾回收。
- // Index.ets
- import router from '@ohos.router';
-
- @Entry
- @Component
- struct MyComponent {
- @State showChild: boolean = true;
-
- // 只有被@Entry装饰的组件才可以调用页面的生命周期
- onPageShow() {
- console.info('Index onPageShow');
- }
- // 只有被@Entry装饰的组件才可以调用页面的生命周期
- onPageHide() {
- console.info('Index onPageHide');
- }
-
- // 只有被@Entry装饰的组件才可以调用页面的生命周期
- onBackPress() {
- console.info('Index onBackPress');
- }
-
- // 组件生命周期
- aboutToAppear() {
- console.info('MyComponent aboutToAppear');
- }
-
- // 组件生命周期
- aboutToDisappear() {
- console.info('MyComponent aboutToDisappear');
- }
-
- build() {
- Column() {
- // this.showChild为true,创建Child子组件,执行Child aboutToAppear
- if (this.showChild) {
- Child()
- }
- // this.showChild为false,删除Child子组件,执行Child aboutToDisappear
- Button('create or delete Child').onClick(() => {
- this.showChild = false;
- })
- // push到Page2页面,执行onPageHide
- Button('push to next page')
- .onClick(() => {
- router.pushUrl({ url: 'pages/Page2' });
- })
- }
-
- }
- }
-
- @Component
- struct Child {
- @State title: string = 'Hello World';
- // 组件生命周期
- aboutToDisappear() {
- console.info('[lifeCycle] Child aboutToDisappear')
- }
- // 组件生命周期
- aboutToAppear() {
- console.info('[lifeCycle] Child aboutToAppear')
- }
-
- build() {
- Text(this.title).fontSize(50).onClick(() => {
- this.title = 'Hello ArkUI';
- })
- }
- }
以上示例中,Index页面包含两个自定义组件,一个是被@Entry装饰的MyComponent,也是页面的入口组件,即页面的根节点;一个是Child,是MyComponent的子组件。
只有@Entry装饰的节点才可以生效页面的生命周期方法,所以MyComponent中声明了当前Index页面的页面生命周期函数。MyComponent和其子组件Child也同时也声明了组件的生命周期函数。
应用冷启动的初始化流程为:MyComponent aboutToAppear --> MyComponent build --> Child aboutToAppear --> Child build --> Child build执行完毕 --> MyComponent build执行完毕 --> Index onPageShow。调用顺序跟 Vue 父子组件生命周期类似,也就是先子后父。
点击"delete Child",if绑定的this.showChild变成false,删除Child组件,会执行Child aboutToDisappear方法。
点击"push to next page",调用router.pushUrl接口,跳转到另外一个页面,当前Index页面隐藏,执行页面生命周期Index onPageHide。此处调用的是router.pushUrl接口,Index页面被隐藏,并没有销毁,所以只调用onPageHide。跳转到新页面后,执行初始化新页面的生命周期的流程。
如果调用的是router.replaceUrl,则当前Index页面被销毁,执行的生命周期流程将变为:Index onPageHide --> MyComponent aboutToDisappear --> Child aboutToDisappear。上文已经提到,组件的销毁是从组件树上直接摘下子树,所以先调用父组件的aboutToDisappear,再调用子组件的aboutToDisappear,然后执行初始化新页面的生命周期流程。
点击返回按钮,触发页面生命周期Index onBackPress,且触发返回一个页面后会导致当前Index页面被销毁。
最小化应用或者应用进入后台,触发Index onPageHide。当前Index页面没有被销毁,所以并不会执行组件的aboutToDisappear。应用回到前台,执行Index onPageShow。
退出应用,执行Index onPageHide --> MyComponent aboutToDisappear --> Child aboutToDisappear。
本文从三个角度梳理了鸿蒙移动开发需要理解的生命周期。
页面也是由组件组成,对于@entry装饰的组件具有页面和组件双重生命周期。
为了能够让大家跟上互联网时代的技术迭代,赶上互联网开发人员寒冬期间一波红利,在这里跟大家分享一下我自己近期学习心得以及参考网上资料整理出的一份最新版的鸿蒙学习提升资料,有需要的小伙伴自行领取,限时开源,先到先得~~~~
需要以上视频学习资料小伙伴
这份手册涵盖了当前鸿蒙 (Harmony OS) 开发技术必掌握的核心知识点
HarmonyOS 概念:
如何快速入门?
开发基础知识:
基于ArkTS 开发:
获取以上文中提到的这份纯血版鸿蒙 (Harmony OS) 开发资料的小伙伴
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。