你是不是也在想——“鸿蒙这么火,我能不能学会?”
答案是:当然可以!
这个专栏专为零基础小白设计,不需要编程基础,也不需要懂原理、背术语。我们会用最通俗易懂的语言、最贴近生活的案例,手把手带你从安装开发工具开始,一步步学会开发自己的鸿蒙应用。
不管你是学生、上班族、打算转行,还是单纯对技术感兴趣,只要你愿意花一点时间,就能在这里搞懂鸿蒙开发,并做出属于自己的App!
📌关注本专栏《零基础学鸿蒙开发》,一起变强!
每一节内容我都会持续更新,配图+代码+解释全都有,欢迎点个关注,不走丢,我是小白酷爱学习,我们一起上路 🚀
全文目录:
- 前言
- 一、先把两个层级分开
- 二、这次实验真正验证什么
- 三、最小工程:只给 onCreate 打一个时间点
- 四、页面侧再放一个“参照物”
- 五、按三轮操作观察日志
- 第一轮:第一次启动
- 第二轮:切后台,再回来
- 第三轮:结束旧实例,再重新启动
- 六、三个最容易理解错的地方
- 1. `onCreate()` 的“Create”创建的是 UIAbility 实例
- 2. `onPageShow()` 可以执行很多次,而 `onCreate()` 不因此重复
- 3. “关闭任务卡片”和“生命周期正常销毁”不要简单画等号
- 七、实际项目里怎么排查
- 开发经验总结
前言
HarmonyOS 应用里有两个很容易被混在一起的问题:UIAbility 什么时候被创建,以及ArkUI 页面什么时候重新显示。
最典型的误解是:应用切到后台,再切回来,页面重新出现在眼前,于是直觉上认为UIAbility.onCreate()也应该再执行一次。实际上,这两个事件属于不同层级。官方对 Stage 模型的说明明确指出,UIAbility 生命周期关注创建、销毁、前台、后台等状态;ArkUI 页面和组件则有自己的生命周期。
这次不展开整个 Ability 生命周期,只盯住一个回调:UIAbility.onCreate()。我们用时间日志做一个最小实验,分别观察第一次启动、切后台再回来、实例结束后重新启动时,它究竟什么时候再次出现。
一、先把两个层级分开
在 Stage 模型中,UIAbility 是包含 UI 的应用组件。每个 UIAbility 实例都有对应的UIAbilityContext,相关接口属于 Ability Kit;官方当前 API 文档明确说明这组 Stage 模型能力从 API version 9 开始提供。
ArkUI 页面则是另一个层级。
以经典@Entry页面为例,官方文档给出的页面级生命周期包括:
onPageShow():页面每次显示时触发,包括页面跳转后重新显示、应用从后台回到前台等场景;onPageHide():页面每次隐藏时触发,包括页面跳转、应用进入后台等场景;aboutToAppear()/aboutToDisappear():属于自定义组件生命周期;.onAppear()/.onDisappear():属于通用组件的生命周期事件,并不是 UIAbility 的生命周期。
所以标题里的“页面 onAppear”更多是在描述常见的口语化混淆。如果严格按照 ArkUI 的术语,页面级“重新显示”更应该拿onPageShow()与UIAbility.onCreate()对照;.onAppear()本身属于通用组件事件。
这一区分非常关键:
| 层级 | 典型对象 | 本文关注的回调 | 表达的含义 |
|---|---|---|---|
| Ability 层 | UIAbility | onCreate() | UIAbility 实例完成创建 |
| ArkUI 页面层 | @Entry页面 | onPageShow() | 页面显示 |
| ArkUI 自定义组件层 | @Component | aboutToAppear() | 自定义组件即将出现 |
| ArkUI 通用组件层 | Text、Column 等 | .onAppear() | 组件挂载到组件树 |
官方对 ArkUI 生命周期的描述还明确给出了一个很有用的现象:应用最小化进入后台时,当前页面会触发onPageHide();回到前台时会再次触发onPageShow(),但页面没有因此被销毁重建。
这已经给我们的实验提供了一个预测:后台 → 前台可以让页面再次 show,但没有理由仅因为这次显示就重新创建 UIAbility 实例。
二、这次实验真正验证什么
实验保持得尽量小,不引入网络、数据库、权限或三方库,只回答一个问题:
UIAbility.onCreate()到底跟“页面显示”绑定,还是跟“UIAbility 实例创建”绑定?
实验分三轮:
- 安装并第一次启动应用,记录
onCreate(); - 将应用切到后台,再从任务中心切回,观察
onCreate()是否再次出现; - 结束当前应用实例后重新启动,再观察
onCreate()。
这里还要把“冷启动”说得更精确一点。
日常开发里经常把“重新打开应用”直接称为冷启动,但本文真正能够通过日志证明的是:是否创建了新的 UIAbility 实例。因此,判断依据不要只看“应用图标是不是重新点了一次”,而要看实例生命周期是否已经结束。
官方提供的UIAbilityContext.terminateSelf()就是明确的“销毁 UIAbility 自身”接口。官方同时说明,调用后任务中心默认仍可能保留任务快照,这说明“最近任务里还有没有卡片”和“UIAbility 实例是否仍存在”本身也不是完全相同的问题。
本文的手工实验可以使用系统任务界面关闭应用;如果要做更严格的自动化验证,则应额外确认旧实例确实已经结束,再讨论下一次启动是不是一次新的实例创建。
三、最小工程:只给 onCreate 打一个时间点
Ability 侧只需要 Ability Kit 和 HiLog。
华为官方当前示例使用:
import{AbilityConstant,UIAbility,Want}from'@kit.AbilityKit';import{hilog}from'@kit.PerformanceAnalysisKit';官方资料中的 UIAbility 示例同样在onCreate(want, launchParam)中使用hilog.info()输出日志。 HiLog 用于输出应用运行日志,其 INFO 日志接口接受 domain、tag、格式字符串和参数;HiLog 能力首批接口从 API version 7 开始支持。
EntryAbility.ets可以写成:
import{AbilityConstant,UIAbility,Want}from'@kit.AbilityKit';import{hilog}from'@kit.PerformanceAnalysisKit';constDOMAIN:number=0x0000;constTAG:string='LifeExperiment';exportdefaultclassEntryAbilityextendsUIAbility{onCreate(want:Want,launchParam:AbilityConstant.LaunchParam):void{consttimestamp:number=Date.now();hilog.info(DOMAIN,TAG,'UIAbility onCreate, timestamp=%{public}d',timestamp);}}这段代码只做一件事:每当EntryAbility.onCreate()真正被系统回调时,留下一个时间戳。
这里没有把业务初始化、页面加载、网络请求之类的逻辑塞进去,因为它们都会干扰观察。实验的核心不是计算启动耗时,而是数清楚onCreate()到底出现了几次。
另外,这个实验本身不需要额外声明运行时权限,也没有新增module.json5权限项。
四、页面侧再放一个“参照物”
如果只打印onCreate(),切后台再回来时控制台什么都不新增,虽然已经能够说明问题,但不够直观。
所以可以在Index.ets里增加页面级日志:
@Entry@Componentstruct Index{onPageShow():void{console.info(`Index onPageShow:${Date.now()}`);}onPageHide():void{console.info(`Index onPageHide:${Date.now()}`);}build(){Column(){Text('UIAbility onCreate lifecycle experiment').fontSize(24)}.width('100%').height('100%')}}onPageShow()和onPageHide()是@Entry页面能够使用的页面生命周期回调。官方生命周期文档明确说明,应用切到后台会触发当前页面的onPageHide(),重新回到前台则触发onPageShow()。
注意,这里添加页面日志的目的只是建立对照,并不是把onPageShow()当成onCreate()的替代品。
真正需要观察的是两条完全不同的时间线:
UIAbility 实例: onCreate() ----------------------------- 实例继续存在 ArkUI 页面: onPageShow() -> onPageHide() -> onPageShow()只要 Ability 实例没有被重新创建,页面经历一次 hide/show,并不意味着 Ability 又经历一次 create。
五、按三轮操作观察日志
第一轮:第一次启动
启动应用后,应重点寻找:
UIAbility onCreate, timestamp=... Index onPageShow: ...这里不要把日志顺序扩展成未经验证的完整系统启动时序。本文只需要确认两个事实:创建 UIAbility 实例时会进入onCreate();页面显示时有自己的页面生命周期。
官方 Stage 模型说明也强调,UIAbility 生命周期与 UI 显示相关状态不是同一个层级。
第二轮:切后台,再回来
按 Home 键或通过系统操作让应用进入后台,然后从任务中心返回。
根据 ArkUI 官方生命周期规则,当前页面进入后台会触发onPageHide(),返回前台时会触发onPageShow()。
因此重点检查日志是否呈现类似结构:
Index onPageHide: ... Index onPageShow: ...而原来的:
UIAbility onCreate, timestamp=...没有因为这次后台 → 前台而新增一条。
这正是本文最想拆开的概念:页面再次可见,不等于 UIAbility 实例再次创建。
如果业务要求“每次应用回到前台都刷新页面数据”,把逻辑机械地塞进UIAbility.onCreate()就会产生生命周期层级上的错位。页面每次重新显示的需求,应根据实际导航架构和页面生命周期选择合适的位置,而不是把onCreate()当作“页面显示事件”。
第三轮:结束旧实例,再重新启动
这一轮才是验证onCreate()边界的关键。
在确认旧 UIAbility 实例已经结束后,再启动应用。此时系统需要创建新的 UIAbility 实例,于是应该再次进入onCreate(),日志中会留下新的时间戳。
因此三轮实验要看的并不是“启动了几次应用界面”,而是:
| 操作 | UIAbility 实例是否需要重新创建 | onCreate()观察重点 |
|---|---|---|
| 首次创建 UIAbility | 是 | 出现 |
| 进入后台 | 否 | 不应把它理解为重新创建 |
| 从后台返回原实例 | 否 | 不应把页面重新显示等同于onCreate() |
| 旧实例结束后重新启动 | 是 | 新实例进入onCreate() |
这里刻意不用“任何情况下都绝对如此”这样的表述,因为启动模式、异常进程终止、系统恢复等场景还会带来其他生命周期路径。本文只验证最普通、最容易复现的一条路径。
六、三个最容易理解错的地方
1.onCreate()的“Create”创建的是 UIAbility 实例
这是最核心的一点。
它不是“创建某个 ArkUI 页面”,也不是“页面每次显示”,更不是“用户每次点击桌面图标”。
官方 API 文档中,每个 UIAbility 实例都会对应创建UIAbilityContext;Stage 模型说明也把 UIAbility 的创建、销毁、前台、后台生命周期与 UI 显示层分开描述。
因此,在onCreate()中更适合考虑与当前 UIAbility 实例建立相关的初始化工作,而不是把所有“页面重新可见时都要执行”的逻辑统一放进去。
2.onPageShow()可以执行很多次,而onCreate()不因此重复
官方对onPageShow()的定义非常直接:页面每次显示都会触发,其中就包括应用从后台切回前台。
这也是为什么单纯看 UI 表现特别容易误判。
用户看到的是:
页面消失 -> 页面又出现Ability 层实际可能只是:
同一个 UIAbility 实例继续存在页面层和 Ability 层同时存在生命周期,并不意味着两个层级的事件是一一对应关系。
3. “关闭任务卡片”和“生命周期正常销毁”不要简单画等号
做生命周期实验时,这一点也很重要。
官方文档明确存在“重启进程但不触发 AbilityonDestroy()”的场景,例如restartApp()的说明就特别指出,通过该接口重启进程不会触发进程中 Ability 的onDestroy回调。
这提醒我们:不能反过来用“我没看到 onDestroy”证明实例一定没有结束。
所以本文判断onCreate()的方法很简单:只观察新启动后有没有新的onCreate()日志,不把onDestroy()当作所有退出场景下都必须出现的前置证据。
七、实际项目里怎么排查
如果发现某段初始化逻辑“第一次打开执行了,切后台回来却没有执行”,建议按下面的顺序检查:
- 先确认代码是不是放在
UIAbility.onCreate()中; - 明确业务想监听的是“UIAbility 实例创建”,还是“页面重新显示”;
- 如果关注页面显示,检查对应
@Entry页面或当前使用的 Navigation 页面生命周期,而不是继续给onCreate()加判断; - 如果认为 Ability 已经重新创建,直接给
onCreate()加带时间戳的日志验证,不要只凭 UI 是否重新出现判断; - 再检查启动模式、页面导航方式以及是否存在进程重启、异常终止等特殊路径。
这个排查方法的价值在于先把生命周期所属层级确定下来。层级弄错之后,业务代码写得再复杂,也只是不断给错误的回调增加补丁。
开发经验总结
这次最小实验真正需要记住的只有几件事。
UIAbility.onCreate()描述的是UIAbility 实例创建,不是 ArkUI 页面每次显示;应用从后台回到前台时,ArkUI 页面可以重新触发onPageShow(),并不意味着 UIAbility 又执行了一次onCreate();而.onAppear()严格来说还是通用组件事件,不能和页面级onPageShow()、Ability 级onCreate()混成同一个概念。
从 API 范围看,本文使用的是 Stage 模型下的 Ability Kit UIAbility 能力以及 ArkUI 页面生命周期,没有额外权限要求,也没有依赖设备专属能力。当前华为开发者文档仍将 UIAbilityContext 标记为 Stage 模型能力,其相关模块首批接口从 API version 9 开始支持;当前 API 文档同时按设备/API 版本展示支持范围。
对于 HarmonyOS 7 项目,本文没有为了“7”这个版本号额外引入任何新版专属接口:示例只依赖已经长期存在的 UIAbility、Want、AbilityConstant、ArkUI 页面生命周期以及 HiLog。由于本文检索到的公开官方页面没有提供一条可直接引用的“HarmonyOS 7 = 某单一 API Level”的统一映射说明,因此这里不强行写死映射数字;实际工程仍应以 DevEco Studio 所使用 SDK 的compileSdkVersion/ API Reference 版本筛选结果为准。这比根据系统大版本名称反推 API Level 更稳妥。
最后可以在自己的工程里做一个很简单的检查:如果某段代码的真实需求是“用户每次重新看到这个页面时执行”,但它现在放在UIAbility.onCreate()里,那么这段逻辑的生命周期层级很可能就值得重新确认了。
❤️ 如果本文帮到了你…
- 请点个赞,让我知道你还在坚持阅读技术长文!
- 请收藏本文,因为你以后一定还会用上!
- 如果你在学习过程中遇到bug,请留言,我帮你踩坑!