ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AbilityStage 的 onCreate 到底什么时候执行?一次模块级初始化实验【鸿蒙心迹】

AbilityStage 的 onCreate 到底什么时候执行?一次模块级初始化实验【鸿蒙心迹】 你是不是也在想——“鸿蒙这么火我能不能学会”答案是当然可以这个专栏专为零基础小白设计不需要编程基础也不需要懂原理、背术语。我们会用最通俗易懂的语言、最贴近生活的案例手把手带你从安装开发工具开始一步步学会开发自己的鸿蒙应用。不管你是学生、上班族、打算转行还是单纯对技术感兴趣只要你愿意花一点时间就能在这里搞懂鸿蒙开发并做出属于自己的App关注本专栏《零基础学鸿蒙开发》一起变强每一节内容我都会持续更新配图代码解释全都有欢迎点个关注不走丢我是小白酷爱学习我们一起上路 全文目录前言一、先把 AbilityStage 的层级弄清楚二、HarmonyOS 7 下需要确认哪些版本信息三、搭一个最小 AbilityStage 实验四、创建自定义 AbilityStage五、module.json5真正让自定义 AbilityStage 生效六、第一次进入和第二次进入到底会发生什么七、什么逻辑适合放在这里八、几个特别容易理解错的地方九、实际项目里怎么排查开发经验总结前言在 Stage 模型里UIAbility.onCreate()很容易理解创建 UIAbility 实例时触发。AbilityStage.onCreate()则更容易被误解有人会把它理解成“应用第一次启动执行一次”也有人把它当成“每次进入应用都会执行”。这两种说法都不够准确。真正决定AbilityStage.onCreate()是否执行的不是用户有没有重新点桌面图标而是这个 HAP 的代码是否正在被加载到进程中并因此创建了新的 AbilityStage 实例。这次不扩展其他生命周期只做一个最小实验给entryHAP 配置自定义 AbilityStage在onCreate()打一条日志然后连续进入应用观察它到底执行几次。一、先把 AbilityStage 的层级弄清楚HarmonyOS 官方对 Stage 模型的定义很明确每个 Entry 类型或 Feature 类型的 HAP 在运行期都有 AbilityStage 实例当该 HAP 中的代码首次被加载到进程时系统会先创建 AbilityStage。之后这个 HAP 中定义的 UIAbility 实例会与该 AbilityStage 产生关联。因此可以先建立这样一个关系应用 ├── entry HAP │ ├── AbilityStage │ ├── EntryAbility │ └── OtherAbility │ └── feature HAP ├── AbilityStage └── FeatureAbilityAbilityStage 不是某个页面的生命周期对象也不是某个 UIAbility 的生命周期对象。它的作用域更接近HAP 模块运行期。官方较早版本的 AbilityStage 专题文档也明确说明在模块的第一个 UIAbility 实例加载前会创建 AbilityStage并在 AbilityStage 实例创建时调用onCreate()这个回调可用于模块初始化。所以本文最核心的一句话是AbilityStage.onCreate()跟随 AbilityStage 实例的创建执行而不是跟随“页面进入次数”执行。二、HarmonyOS 7 下需要确认哪些版本信息截至本文资料核对时间华为官方 2026 年 8 月开发者月刊已经明确 HarmonyOS 7 对应 API 26并已正式发布配套文档。官方同月资料还新增了“应用启动流程”指导将应用启动划分为进程启动、AbilityStage 启动、UIAbility 启动三个阶段。AbilityStage 属于 Ability Kit 的 Stage 模型能力。当前官方 API 目录仍提供ohos.app.ability.AbilityStage推荐 Kit 化导入方式为kit.AbilityKit与 AbilityStage 对应的AbilityStageContext首批接口从 API version 9 开始支持并且只能用于 Stage 模型。当前官方示例同样使用import { AbilityStage } from kit.AbilityKit。本文实验的边界可以整理为项目本文使用情况开发背景HarmonyOS 7 / API 26应用模型Stage 模型KitAbility Kit、Performance Analysis Kit核心类AbilityStage核心回调onCreate(): void模块配置module.json5的module.srcEntry额外权限本实验只打印生命周期日志不新增requestPermissions实验对象Entry/Feature 类型 HAP 的 AbilityStage这里还要区分两个srcEntry。module.abilities[].srcEntry指向具体 UIAbility 的代码入口而本文要配置的是module.srcEntry它位于module对象这一层用来指定 AbilityStage 源文件。华为当前的独立进程开发指导同样使用module.srcEntry指向自定义 AbilityStage。三、搭一个最小 AbilityStage 实验实验目标非常简单第一次启动并加载 entry HAP ↓ 创建 AbilityStage ↓ 执行 AbilityStage.onCreate() ↓ 输出一条日志 应用仍在当前运行期 ↓ 再次进入 ↓ 不重新创建 AbilityStage ↓ 不应新增 onCreate 日志为了尽量减少干扰不在UIAbility、页面和 ArkUI 组件里增加计数逻辑只观察 AbilityStage 自己的日志。建议在entry/src/main/ets/下新建myabilitystage/ └── MyAbilityStage.ets四、创建自定义 AbilityStage这段代码只解决一件事当 AbilityStage 被创建时输出日志同时把当前 HAP 模块名打印出来。// entry/src/main/ets/myabilitystage/MyAbilityStage.etsimport{AbilityStage}fromkit.AbilityKit;import{hilog}fromkit.PerformanceAnalysisKit;constDOMAIN:number0x0000;constTAG:stringStageInitLab;exportdefaultclassMyAbilityStageextendsAbilityStage{onCreate():void{constmoduleName:stringthis.context.currentHapModuleInfo.name;hilog.info(DOMAIN,TAG,AbilityStage onCreate, module%{public}s,moduleName);}}这里真正需要关注的是三个地方。AbilityStage从kit.AbilityKit导入日志使用官方文档示例中常见的kit.PerformanceAnalysisKit而this.context对应AbilityStageContext可以通过currentHapModuleInfo获取当前 AbilityStage 对应 HAP 的模块信息。官方当前的AbilityStageContext示例本身就是在AbilityStage.onCreate()中读取这些信息。我们没有在这里人为维护“执行次数”。原因也很简单如果进程结束内存里的计数变量同样会消失。本文要观察的是生命周期本身所以直接数 HiLog 中AbilityStage onCreate出现了几次反而更清楚。五、module.json5真正让自定义 AbilityStage 生效只创建MyAbilityStage.ets还不够还需要告诉系统这个 HAP 的 AbilityStage 入口在哪里。在entry/src/main/module.json5的module对象中加入srcEntry{ module: { name: entry, type: entry, srcEntry: ./ets/myabilitystage/MyAbilityStage.ets, // 原工程中的其他配置继续保留 // abilities: [...] } }这里不要把srcEntry错放进abilities数组。官方当前文档给出的 AbilityStage 配置方式同样是在module层配置srcEntry: ./ets/MyAbilityStage/MyAbilityStage.ets然后由该文件中的类继承AbilityStage。换句话说module.srcEntry决定的是“这个 HAP 的 AbilityStage 从哪里加载”而abilities[i].srcEntry决定的是“这个 UIAbility 的实现文件在哪里”。两个字段名字相同但配置层级和含义不能混用。六、第一次进入和第二次进入到底会发生什么配置完成后可以在 DevEco Studio 的日志窗口中过滤StageInitLab。这里必须强调下面是根据官方生命周期定义得到的预期观察结果不是本文声称已经替读者完成了真机运行。当进程中尚未加载这个 HAP而启动行为使entryHAP 的代码首次加载时系统会创建 AbilityStage因此应该看到一次AbilityStage onCreate, moduleentry如果随后只是让应用进入后台再在原进程、原 HAP 运行期仍然存在的前提下重新进入应用并没有创建新的 AbilityStage那么不应该因为“又进入了一次应用”而再执行一次AbilityStage.onCreate()。官方定义的关键条件始终是“HAP 中的代码首次被加载到进程”以及 AbilityStage 实例的创建。实验结果应该按下面的逻辑理解操作场景AbilityStage 是否重新创建onCreate()预期当前进程尚未加载该 HAP第一次触发加载是执行应用进入后台后在原运行期内再次进入否不新增执行原进程已经结束之后再次启动并重新加载 HAP是再执行另一个 Entry/Feature HAP 首次被加载创建该 HAP 自己的 AbilityStage对应 HAP 执行所以“AbilityStage.onCreate()只执行一次”也是一个容易误导人的说法。更准确的表达应该是在同一个 AbilityStage 实例的生命周期里onCreate()在实例创建时执行一次如果后续因为新的运行期再次创建 AbilityStage它仍然会再次执行。它不是“安装应用以后永远只执行一次”也不是“每天第一次打开执行一次”更不是“每点一次桌面图标执行一次”。七、什么逻辑适合放在这里理解执行时机之后AbilityStage.onCreate()的定位就清楚很多了它适合承载跟 HAP 模块加载绑定的初始化工作而不是页面级初始化。官方 AbilityStage 指南把资源预加载、线程创建作为模块初始化的典型例子。 实际工程中可以沿着这个边界判断某项初始化如果属于整个 HAP而不是某一个 UIAbility 或某一个页面并且希望在 HAP 开始运行时完成那么 AbilityStage 是可以考虑的位置。但这里还有一个很重要的限制不要因为它“足够早”就把所有启动逻辑都塞进去。华为当前 Call Service Kit 的官方开发指导给出了一个很直接的例子某些 ExtensionAbility 场景在业务回调前会先创建应用的 AbilityStage因此官方明确提醒不要在 AbilityStage 中加入过于复杂、耗时的逻辑以免影响后续调用甚至造成超时。这条提醒虽然出现在具体业务能力文档里但对理解 AbilityStage 的位置很有价值它位于组件启动链路的前面阻塞这里就可能把后续组件一起挡住。因此更合适的原则是模块级、必要、轻量。例如建立轻量级模块状态、读取已经就绪的模块配置、启动必要的模块初始化入口可以考虑放这里需要大量 I/O、复杂依赖编排或者明显耗时的任务则应该重新评估是否有必要阻塞 AbilityStage 创建阶段。八、几个特别容易理解错的地方第一个误区是把 AbilityStage 当成 Application。Stage 模型的官方描述是“每个 Entry 或 Feature 类型 HAP 在运行期都有一个 AbilityStage 实例”它天然带有 HAP 模块边界。 因此多 HAP 应用尤其不能简单把某个entryHAP 的 AbilityStage 理解成整个应用所有模块唯一的初始化入口。第二个误区是用“打开应用次数”推导执行次数。用户回到桌面再重新进入只描述了 UI 行为并不能说明 AbilityStage 是否重新创建。判断时应该问的是原来的进程和 AbilityStage 实例还在不在这个 HAP 是否需要重新加载第三个误区是漏掉module.srcEntry。文件写得再正确没有在 HAP 的module.json5中把srcEntry指向它自定义 AbilityStage 就没有按照本文方式建立入口。当前官方文档中的 AbilityStage 使用场景同样要求通过该字段指定源文件。第四个误区是把 UI 初始化放进这里。AbilityStage 创建发生在 UIAbility 之前它并不是 ArkUI 页面生命周期。如果逻辑依赖具体 UIAbility、WindowStage 或页面组件就应该回到对应层级处理而不是为了“早点执行”强行塞进 AbilityStage。九、实际项目里怎么排查如果发现AbilityStage.onCreate()没有按预期出现可以按一个比较短的顺序检查。先确认工程使用的是 Stage 模型再检查自定义类是否继承AbilityStageimport 是否使用当前推荐的kit.AbilityKit接着检查module.json5中配置的是module.srcEntry路径是否真正指向MyAbilityStage.ets然后过滤 HiLog 的 TAG确认不是日志没有被看到如果发现日志“又执行了一次”不要先怀疑生命周期异常而要确认此前应用进程是否已经结束、HAP 是否发生了重新加载。涉及多 HAP 或独立进程时还要把“哪个 HAP、哪个进程中的 AbilityStage”一起纳入判断。Stage 模型当前的官方定义本身就是以 HAP 加载到进程作为 AbilityStage 创建边界。开发经验总结AbilityStage.onCreate()最容易记错的地方其实不是 API 写法而是“模块级”三个字。它早于 HAP 中 UIAbility 实例的正常使用阶段是 AbilityStage 实例创建时的初始化入口同一运行期内反复进入应用并不等价于反复创建 AbilityStage进程结束后重新加载 HAP则可能创建新的 AbilityStage因此不能把它理解成“应用安装后永久只执行一次”。配置上真正关键的是module.json5的module.srcEntry。代码层面反而非常简单继承AbilityStage实现onCreate(): void然后把初始化控制在合理范围内。如果要判断一段代码该不该放这里可以问自己一句“这段逻辑属于某个页面、某个 UIAbility还是属于这个 HAP 本身”如果答案明确是 HAP 模块而且它又确实需要在模块加载阶段完成AbilityStage.onCreate()才是值得考虑的位置。这也是这次最小实验真正想验证的东西不要用“用户打开了几次应用”理解 AbilityStage要用HAP 是否重新加载、AbilityStage 是否重新创建来理解它。❤️ 如果本文帮到了你…请点个赞让我知道你还在坚持阅读技术长文请收藏本文因为你以后一定还会用上如果你在学习过程中遇到bug请留言我帮你踩坑
返回列表