
1 -> 为什么需要预加载?冷启动之痛与系统级破局
对于任何一款应用,启动速度都是用户的第一道体验门槛。想象一下,你点击一个游戏图标,却要盯着黑屏等待数秒——这期间用户很可能已经失去耐心。尤其是大型应用(如游戏、复杂的办公软件),冷启动时需要完成进程创建、资源加载、框架初始化等一系列操作,耗时往往很长。
传统的优化思路大多集中在应用内部:代码瘦身、异步加载、延迟初始化……这些手段虽然有效,但终究受限于设备性能和系统调度。有没有一种方式,能让系统在用户真正打开应用之前,就提前'预热'好一部分工作?
鸿蒙给出的答案是:应用预加载机制。 这不是简单的后台保活,而是一种基于用户行为预测的智能调度。系统会学习你的使用习惯——比如每天中午 12 点会打开某个办公应用,或者晚上 8 点会启动游戏——并在设备空闲、资源充裕时,悄悄地将这些应用加载到特定阶段。等到你真正点击图标时,应用就像已经热好身的运动员,只待最后冲刺。
这种机制的好处在于:
- 对用户:感知到的启动时间极大缩短,体验更流畅。
- 对开发者:无需在应用内写大量复杂的预判逻辑,只需声明希望预加载到哪个阶段,其余交给系统。
- 对系统:充分利用闲置资源,提升整体调度效率。
2 -> 预加载的运行机制:三个阶段,层层深入
预加载并非一揽子方案,而是提供了三个可选阶段,开发者可以根据应用自身的冷启动耗时分布来选择。这三个阶段就像'预热'的三个档位:越深的档位,提前完成的工作越多,启动时剩的工作越少,但预加载本身对资源的消耗也越大。
2.1 -> processCreated:只建进程,不跑代码
这是最浅的预加载阶段。当系统决定预加载你的应用时,它会:
- 创建一个空的应用进程。
- 初始化 Application 对象(即加载应用级别的资源、执行 Application 的 attachBaseContext 等,但不会调用任何生命周期回调,如 onCreate)。
这个阶段的意义在于,进程创建本身是有开销的——系统需要为应用分配地址空间、启动主线程、加载基础库。如果能在后台提前完成这一步,那么当用户点击图标时,应用就已经有了一个现成的进程,直接进入 Ability 的创建流程,省去了进程创建的时间。
适合场景:那些进程创建耗时占比较高的应用,或者你暂时不想让任何代码提前执行,仅想节省进程创建开销。
2.2 -> abilityStageCreated:让 AbilityStage 活起来
AbilityStage 是 HAP 包(特别是 entry 模块)的容器,它会在应用进程创建后、第一个 UIAbility 创建之前被初始化。预加载到这一阶段时,系统会:
- 完成 processCreated 的所有工作。
- 触发 entry 模块 AbilityStage 的 onCreate 生命周期回调。
在这个回调里,你可以执行一些全局的、不依赖 UI 的初始化操作。例如:
- 初始化数据库连接池。
- 预加载一些通用的配置数据。
- 设置全局异常监听器。
关键点:由于此时没有界面,任何涉及 UI 显示或交互的操作都不能在这里做。比如弹 Toast、显示对话框、甚至依赖 Window 的 API 都是危险的——因为 WindowStage 还没创建。开发者需要在 onCreate 里通过 launchParam.launchReason 判断是否为预加载启动(仅 windowStageCreated 阶段可用),但 abilityStageCreated 阶段无法直接判断,但你可以通过其他方式(如静态变量)来标记当前是预加载环境,避免执行 UI 相关代码。
2.3 -> windowStageCreated:提前拉起 UIAbility
这是最深度的预加载阶段。系统会:
- 完成前两个阶段的所有工作。
- 拉起 entry 模块的入口 UIAbility(即 module.json5 中 mainElement 指定的 Ability)。


