【鸿蒙开发】生命周期

news2025/1/18 21:14:29

1. UIAbility组件生命周期

UIAbility的生命周期包括Create、Foreground、Background、Destroy四个状态。

UIAbility生命周期状态

 1.1 Create状态

Create状态为在应用加载过程中,UIAbility实例创建完成时触发,系统会调用onCreate()回调。可以在该回调中进行页面初始化操作,例如变量定义资源加载等,用于后续的UI界面展示。

import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';

export default class EntryAbility extends UIAbility {
    onCreate(want, launchParam) {
        // 页面初始化
    }
    // ...
}

1.2 WindowStageCreate和WindowStageDestroy状态

UIAbility实例创建完成之后,在进入Foreground之前,系统会创建一个WindowStage。WindowStage创建完成后会进入onWindowStageCreate()回调,可以在该回调中设置UI界面加载、设置WindowStage的事件订阅。

在onWindowStageCreate()回调中通过loadContent()方法设置应用要加载的页面并根据需要订阅WindowStage的事件(获焦/失焦、可见/不可见)。

import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';

export default class EntryAbility extends UIAbility {
    onWindowStageCreate(windowStage: Window.WindowStage) {
        // 设置WindowStage的事件订阅(获焦/失焦、可见/不可见)

        // 设置UI界面加载
        windowStage.loadContent('pages/Index', (err, data) => {
            // ...
        });
    }
}

在UIAbility实例销毁之前会进入onWindowStageDestroy()回调,可以释放UI界面资源。

import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';

export default class EntryAbility extends UIAbility {
    // ...

    onWindowStageDestroy() {
        // 释放UI界面资源
    }
}
  • onCreate:在 Ability 创建时被调用,用于执行初始化和设置业务逻辑。
  • onDestroy:在 Ability 销毁时触发,用于执行资源清理和其他清理操作。
  • onWindowStageCreate:在 WindowStage 创建完成后触发。
  • onWindowStageDestroy:在 WindowStage 销毁后触发。
  • onForeground:Ability 的生命周期回调,当应用从后台切换到前台时调用。
  • onBackground:Ability 的生命周期回调,当应用从前台切换到后台时调用。

2. 页面和自定义组件生命周期

2.1 页面生命周期

即被@Entry装饰的组件生命周期,提供以下生命周期接口:

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

2.2 组件生命周期

即一般用@Component装饰的自定义组件的生命周期,提供以下生命周期接口:

  • aboutToAppear:组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build()函数之前执行。
  • aboutToDisappear:在自定义组件析构销毁之前执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定。

2.3 生命周期流程

下图展示的是被@Entry装饰的组件(页面)生命周期。

2.4 自定义组件的渲染流程

  • ArkUI框架创建自定义组件
  • 初始化自定义组件的成员变量
  • 执行aboutToAppear方法
  • 执行build方法渲染组件,在首次渲染时,框架会记录状态变量和组件的映射关系
  • 当状态变量的值更改时,框架根据映射关系,执行这些UI组件的更新函数
  • if分支或者ForEach渲染的数组个数改变,组件将被删除,在删除前执行aboutToDisappear

不建议在aboutToDisappear内使用async await,如果在aboutToDisappear使用中Promise或者回调方法,自定义组件将被保留在Promise的闭包中,直到回调方法被执行完,这个行为阻止了自定义组件的垃圾回收。

 2.5 示例

import router from '@ohos.router'

@Entry
@Component
struct Index {
  @State showChild: boolean = true;

  // 页面生命周期
  onPageShow() {
    console.info('Index onPageShow');
  }
  // 页面生命周期
  onPageHide() {
    console.info('Index onPageHide');
  }
  // 页面生命周期
  onBackPress() {
    console.info('Index onBackPress');
  }

  // 组件生命周期
  aboutToAppear() {
    console.info('Index aboutToAppear');
  }
  // 组件生命周期
  aboutToDisappear() {
    console.info('Index aboutToDisappear');
  }

  build() {
    Column() {
      // this.showChild为true,创建Child子组件,执行Child aboutToAppear
      if (this.showChild) {
        Child()
      }
      // this.showChild为false,删除Child子组件,执行Child aboutToDisappear
      Button('删除子组件 Child')
        .margin({ bottom: 20 })
        .onClick(() => {
          this.showChild = false;
        })
      // push到DetailPage页面,执行onPageHide
      Button('跳转到 DetailPage')
        .onClick(() => {
          router.pushUrl({ url: 'pages/DetailPage' });
        })
    }
    .width("100%")
    .height("100%")
  }
}

@Component
struct Child {
  @State title: string = 'Child';

  // 组件生命周期
  aboutToAppear() {
    console.info('Child aboutToAppear')
  }
  // 组件生命周期
  aboutToDisappear() {
    console.info('Child aboutToDisappear')
  }

  build() {
    Text(this.title).fontSize(50).onClick(() => {
      this.title = 'Child Click';
    })
  }
}

3. 同模块下的UIAbility跳转

3.1 创建 PaymentPage

@Entry
@Component
struct PaymentPage {
  @State message: string = 'payment page'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}

3.2 创建 PaymentAbility

修改 windowStage.loadContent 加载的页面

3.3 修改 Index.ets

import common from '@ohos.app.ability.common'
import Want from '@ohos.app.ability.Want'

@Entry
@Component
struct Index {
  @State message: string = 'index page'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)

        Button("去支付")
          .width('100%')
          .onClick(() => {
            const context = getContext(this) as common.UIAbilityContext;
            const want: Want = {
              'deviceId': '', // deviceId为空表示本设备
              'bundleName': 'com.example.myapplication',
              'abilityName': 'PaymentAbility',
              'moduleName': 'entry'
            }
            context.startAbility(want)
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

4. 不同模块下的UIAbility跳转

4.1 创建模块

4.2 修改 paymentModule 模块的 Index.ets

@Entry
@Component
struct Index {
  @State message: string = 'payment module page'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}

4.3 修改 entry 模块的 Index.ets

修改 abilityName 和 moduleName

import common from '@ohos.app.ability.common'
import Want from '@ohos.app.ability.Want'

@Entry
@Component
struct Index {
  @State message: string = 'index page'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)

        Button("去支付")
          .width('100%')
          .onClick(() => {
            const context = getContext(this) as common.UIAbilityContext;
            const want: Want = {
              'deviceId': '', // deviceId为空表示本设备
              'bundleName': 'com.example.myapplication',
              'abilityName': 'PaymentModuleAbility',
              'moduleName': 'paymentModule'
            }
            context.startAbility(want)
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

4.4 配置调起2个模块

 

4.5 两个模块之间传递数据

4.5.1 修改 entry 模块的 Index.ets

使用 parameters 选项添加自定义数据

使用 context.startAbilityForResult 方法启动 UIAbility 并获取返回结果

import common from '@ohos.app.ability.common'
import Want from '@ohos.app.ability.Want'

type PaymentAbilityParams = Record<string, boolean>

@Entry
@Component
struct Index {
  @State message: string = 'index page'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)

        Button("去支付")
          .width('100%')
          .onClick(async () => {
            const context = getContext(this) as common.UIAbilityContext;
            const want: Want = {
              deviceId: '', // deviceId为空表示本设备
              bundleName: 'com.example.myapplication',
              abilityName: 'PaymentModuleAbility',
              moduleName: 'paymentModule',
              parameters: {
                orderId: Date.now()
              }
            }
            // context.startAbility(want)
            const paymentAbilityResult = await context.startAbilityForResult(want)
            const params = paymentAbilityResult.want?.parameters as PaymentAbilityParams
            if (params?.isPay) {
              AlertDialog.show({
                message: "支付成功"
              })
            } else {
              AlertDialog.show({
                message: "支付失败"
              })
            }
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}
4.5.2 修改 paymentModule 模块的 PaymentModuleAbility

在 UIAbility 的 onCreate 中接收参数,并保存到 AppStorage 中

import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';

type AbilityParams = Record<string, number>

export default class PaymentModuleAbility extends UIAbility {
  onCreate(want, launchParam) {
    const params = want.parameters as AbilityParams;
    AppStorage.SetOrCreate<number>("orderId", params.orderId);
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  }

  onDestroy() {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
  }

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

    windowStage.loadContent('pages/Index', (err, data) => {
      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. Data: %{public}s', JSON.stringify(data) ?? '');
    });
  }

  onWindowStageDestroy() {
    // Main window is destroyed, release UI related resources
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  }

  onForeground() {
    // Ability has brought to foreground
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
  }

  onBackground() {
    // Ability has back to background
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
  }
}
4.5.3 修改 paymentModule 模块的 Index.ets

从 storage 中获取 orderId

点击支付按钮, PaymentModuleAbility 停止自身并返回结果

import common from '@ohos.app.ability.common'

@Entry
@Component
struct Index {
  @State message: string = 'payment module page'
  @StorageProp("orderId") orderId: number = 0

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)

        Text(`${this.orderId}`)
          .fontSize(50)
          .fontColor(Color.Red)

        Button("支付").onClick(() => {
          const context = getContext(this) as common.UIAbilityContext;
          context.terminateSelfWithResult({
            resultCode: 1,
            want: {
              deviceId: '', // deviceId为空表示本设备
              bundleName: 'com.example.myapplications',
              abilityName: 'EntryAbility',
              moduleName: 'entry',
              parameters: {
                isPay: true
              }
            }
          })
        })
      }
      .width('100%')
    }
    .height('100%')
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1608274.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

了解 Python 底层的解释器 CPython 和 Python 的对象模型

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、CPython CPython 是 Python 编程语言的官方和最广泛使用的实现。它是用 C 语言编写的&#xff0c;因此得名 “CPython”。作为 Python 生态系统的核心&#xff0c;了解 CPython 的工作原理、主要特…

数据结构- 顺序表-单链表-双链表 --【求个关注!】

文章目录 一 顺序表代码&#xff1a; 二 链表单链表双向链表 一 顺序表 顺序表是线性表的一种 所谓线性表指一串数据的组织存储在逻辑上是线性的&#xff0c;而在物理上不一定是线性的 顺序表的底层实现是数组&#xff0c;其由一群数据类型相同的元素组成&#xff0c;其在逻辑…

bug(警告):[vue-router] Duplicate named routes definition: …

查看警告&#xff1a;[vue-router] Duplicate named routes definition——翻译[vue-router]重复命名路由定义 小编劝诫&#xff1a;当我们在开发过程中警告也一定不要忽略&#xff0c;虽然你在本地跑代码时这些警告影响项目的正常运行&#xff0c;但是会让你产生误区&#xff…

【MIT6.824】lab2C-persistence, lab2D-log compaction 实现笔记

引言 lab2C的实验要求如下 Complete the functions persist() and readPersist() in raft.go by adding code to save and restore persistent state. You will need to encode (or “serialize”) the state as an array of bytes in order to pass it to the Persister. Us…

《游戏系统设计十二》灵活且简单的条件检查系统

目录 1、序言 2、需求 3、实现 3.1 思路 3.2 代码实现 4、总结 1、序言 每个游戏都有一些检查性的任务&#xff0c;在做一些判断的时候&#xff0c;判断等级是不是满足需求。 比如如下场景&#xff1a;在进入副本的时候需要检查玩家等级是否满足&#xff0c;满足之后才…

配置linux的oracle 21c启停服务

一、配置启停 1、使用root用户登陆 su - root 2、修改oratab文件 修改oratab文件&#xff0c;将红框里面的N改为“Y”&#xff0c;使启停脚本能够生效 vi /etc/oratab 3、验证 配置好后就能够使用 dbshut 停止服务 和 dbstart 启动服务 了 2.1启动服务 su - oracle dbstart…

现代商业中首席人工智能官(CAIO)的角色与影响

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Spark01

Spark01 一. Spark概述二. Spark环境部署 - Local三. Spark环境部署 - Standalone1. Standalone集群概述2. Standalone环境部署3. 测试环境 四. Spark环境部署 - Standalone-HA1. 安装部署Zookeeper1. 下载2. zookeeper安装3. 配置StandAlone-HA集群 五. Spark On YARN -- 重点…

深入挖掘C语言 ---- 文件操作

目录 1. 文件的打开和关闭1.1 流和标准流1.1.1流1.1.2标准流 1.2 文件指针1.3 文件的打开和关闭 2. 顺序读写3. 随机读写3.1 fseek3.2 ftell3.3 rewind 4. 读取结束判定 正文开始 1. 文件的打开和关闭 1.1 流和标准流 1.1.1流 我们程序的数据需要输出到各种外部设备, 也需要…

小白也能看懂的BEV感知技术(二)

1. 引言 在自动驾驶的领域中&#xff0c;BEV&#xff08;Birds Eye View&#xff0c;鸟瞰图&#xff09;感知技术扮演着至关重要的角色。它允许自动驾驶车辆从上帝视角“看到”周围的环境&#xff0c;就像一只鸟从空中俯瞰地面一样。这项技术对于理解车辆周围的复杂场景至关重…

【Linux系统】地址空间 Linux内核进程调度队列

1.进程的地址空间 1.1 直接写代码&#xff0c;看现象 1 #include<stdio.h>2 #include<unistd.h>3 4 int g_val 100;5 6 int main()7 {8 int cnt 0;9 pid_t id fork();10 if(id 0)11 {12 while(1)13 {14 printf(&…

javaagent使用

Java Agent是什么&#xff1f; Java Agent是Java平台提供的一个强大工具&#xff0c;它可以在运行时修改或增强Java应用程序的行为。是在JDK1.5以后引入的&#xff0c;它能够在不影响正常编译的情况下修改字节码&#xff0c;相当于是在main方法执行之前的拦截器&#xff0c;也叫…

Python | Leetcode Python题解之第32题最长有效括号

题目&#xff1a; 题解&#xff1a; class Solution:def longestValidParentheses(self, s: str) -> int:stack[]maxL0nlen(s)tmp[0]*n #标记数组cur0for i in range(n):if s[i](:stack.append(i)else:if stack:jstack.pop()if s[j](:tmp[i],tmp[j]1,1 #匹配成…

【C++】:C++关键字,命名空间,输入输出,缺省参数

目录 一&#xff0c;C关键字(C98)二&#xff0c;命名空间2.1 命名冲突2.2 关键字namespace2.2.1 命名空间中可以定义变量/函数/类型2.2.2 命名空间可以嵌套2.2.3 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。 2.3 命名空间的使用2.3.1 指定…

多模态AnyGPT——整合图像、语音和文本多模态大规模语言模型算法原理与实践

概述 大规模语言模型在理解和生成人类语言方面具有非凡的能力&#xff0c;但迄今为止&#xff0c;它们的能力主要局限于文本处理。然而&#xff0c;现实世界是一个多模式的环境&#xff0c;信息通过视觉、听觉和触觉等多种感官进行交换。融入这种多样性是开发下一代系统的主要…

桥接模式【结构型模式C++】

1.概述 桥接模式是一种结构型设计模式&#xff0c;是用于把抽象化与实现化解耦&#xff0c;使得二者可以独立变化。这种类型的设计模式属于结构型模式&#xff0c;它通过提供抽象化和实现化之间的桥接结构&#xff0c;来实现二者的解耦。 这种模式涉及到一个作为桥接的接口&am…

高斯溅射融合之路(一)- webgl渲染3d gaussian splatting

大家好&#xff0c;我是山海鲸的技术负责人。之前已经写了一个GIS融合系列。其实CesiumJS的整合有相当的难度&#xff0c;同时也有很多方面的工作&#xff0c;很难在几篇文章内写完&#xff0c;整个山海鲸团队也是投入了接近两年的时间&#xff0c;才把周边整套工具链进行了完善…

算法复杂度分析笔记

基本定义间的关系 算法介绍 算法分析 时间复杂度 用数量级刻画&#xff1a;忽略所有低次幂项和系数 eg1: eg2: eg3: eg4: 小结 空间复杂度 eg: 总结

Vue3从入门到实践:深度了解新组件

1.Teleport 概念&#xff1a;Teleport&#xff08;传送门&#xff09;是一个新的特性&#xff0c;用于在DOM中的任意位置渲染组件。它允许你将组件的内容渲染到DOM中的另一个位置&#xff0c;而不受组件层次结构的限制。 下面举出例子解释&#xff1a; 1.新建App.vue文件作…

YOLOv9改进策略 | Neck篇 | 2024.1最新MFDS-DETR的HS-FPN改进特征融合层(轻量化Neck、全网独家首发)

一、本文介绍 本文给大家带来的改进机制是最近这几天最新发布的改进机制MFDS-DETR提出的一种HS-FPN结构&#xff0c;其是一种为白细胞检测设计的网络结构&#xff0c;主要用于解决白细胞数据集中的多尺度挑战。它的基本原理包括两个关键部分&#xff1a;特征选择模块和特征融合…