

子玥酱 (掘金 / 知乎 / CSDN / 简书 同名)
大家好,我是 子玥酱,一名长期深耕在一线的前端程序媛 👩💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。
我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括 前端工程化、小程序、React / RN、Flutter、跨端方案,
在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。
技术方向: 前端 / 跨端 / 小程序 / 移动端工程化 内容平台: 掘金、知乎、CSDN、简书 创作特点: 实战导向、源码拆解、少空谈多落地 **文章状态:**长期稳定更新,大量原创输出
我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在"API 怎么用",而是更关注为什么这么设计、在什么场景下容易踩坑、真实项目中如何取舍,希望能帮你在实际工作中少走弯路。
子玥酱 · 前端成长记录官 ✨
👋 如果你正在做前端,或准备长期走前端这条路
📚 关注我,第一时间获取前端行业趋势与实践总结
🎁 可领取 11 类前端进阶学习资源 (工程化 / 框架 / 跨端 / 面试 / 架构)
💡 一起把技术学"明白",也用"到位"
持续写作,持续进阶。
愿我们都能在代码和生活里,走得更稳一点 🌱
文章目录
-
- 引言
- 一、结论版状态机
- 二、为什么必须有这些状态?
- [1、 Created:对象存在,但什么都别干](#1、 Created:对象存在,但什么都别干)
- [2、 Ready:资源就绪,但还不能跑](#2、 Ready:资源就绪,但还不能跑)
- [3、 Running:唯一允许推进世界的状态](#3、 Running:唯一允许推进世界的状态)
- [4、 Suspended:最容易被忽略、但最关键](#4、 Suspended:最容易被忽略、但最关键)
- [5、 Frozen:随时可能被杀的临界态](#5、 Frozen:随时可能被杀的临界态)
- [6、 Destroyed:结束,但不是失败](#6、 Destroyed:结束,但不是失败)
- [三、Ability 生命周期如何映射到运行态?](#三、Ability 生命周期如何映射到运行态?)
- 四、一个可执行的状态机实现示例
- 五、这张状态机真正解决了什么问题?
- 六、一句掏心窝子的总结
引言
如果你还在用这种心智模型:
Init → Running → Pause → Resume → Exit
那在 HarmonyOS 上,迟早会翻车。
不是你写错了,是状态不够。
一、结论版状态机
先别急着反驳,完整跑一遍:
┌──────────┐
│ Created │
└────┬─────┘
│ init
▼
┌──────────┐
│ Ready │
└────┬─────┘
│ start
▼
┌──────────┐
│ Running │◄─────────────┐
└────┬─────┘ │
│ │ resume
│ loseFocus │
▼ │
┌──────────┐ │
│ Suspended│──────────────┘
└────┬─────┘
│ snapshotSaved
▼
┌──────────┐
│ Frozen │
└────┬─────┘
│ reclaim
▼
┌──────────┐
│Destroyed │
└──────────┘
注意:
- 这是「运行态」状态机
- 不是 Ability 生命周期图
- 也不是 UI 显示状态
二、为什么必须有这些状态?
1、 Created:对象存在,但什么都别干
text
内存已分配
逻辑未启动
资源未加载
典型来源:
- Ability 创建
- 后台恢复
- Snapshot 重建
这一阶段的铁律是:
不启动 Loop,不加载大资源,不碰 GPU。
ts
runtime = new GameRuntime()
就到此为止。
2、 Ready:资源就绪,但还不能跑
这是很多游戏压根没有的状态。
text
配置已读
资源可用
世界未推进
为什么必须有?因为在 HarmonyOS 上,你经常会遇到:
- Ability 已创建
- 但窗口还没 ready
- 或焦点未到位
- 或 GPU 上下文未绑定
ts
await runtime.prepare()
但:
ts
不进入 update()
不进入 render()
3、 Running:唯一允许推进世界的状态
text
逻辑更新
物理模拟
动画推进
渲染提交
只有这一态能改世界状态。
ts
if (state === Running) {
update(delta)
render()
}
这一条可以救你 80% 的状态 bug。
4、 Suspended:最容易被忽略、但最关键
这是 HarmonyOS 的"灵魂态"。
text
Ability 失焦
窗口不可交互
游戏逻辑必须停
资源仍在
它和 Pause 的本质区别在于:
不是玩家按了暂停,而是系统把你"按住了"。
你必须在这里:
- 停止 GameLoop
- 停止音频
- 停止物理
- 停止输入响应
但:
text
不释放资源
不清空状态
ts
runtime.suspend()
5、 Frozen:随时可能被杀的临界态
Frozen 是:
系统认为你暂时不重要,但可能还会回来。
此时你必须已经完成:
- 状态快照
- 可恢复数据落盘
- 引擎处于可重建状态
ts
runtime.freeze(snapshot)
这里再做事,就已经太晚了。
6、 Destroyed:结束,但不是失败
text
进程结束
内存回收
对象失效
Destroyed ≠ 游戏结束
而是:
本轮运行结束
下次启动:
Created → Ready → Restore → Running
三、Ability 生命周期如何映射到运行态?
推荐映射关系:
| Ability 回调 | 运行态变化 |
|---|---|
| onCreate | Created |
| onForeground | Ready → Running |
| onFocusLost | Running → Suspended |
| onBackground | Suspended → Frozen |
| onDestroy | Destroyed |
重点:
- 不要一一对应
- 而是"多对一 / 一对多"映射
四、一个可执行的状态机实现示例
ts
enum RuntimeState {
Created,
Ready,
Running,
Suspended,
Frozen,
Destroyed
}
class GameRuntime {
private state: RuntimeState = RuntimeState.Created
transition(next: RuntimeState) {
if (!this.isValid(this.state, next)) return
this.state = next
}
update(delta: number) {
if (this.state !== RuntimeState.Running) return
// safe update
}
}
你会发现:
状态机本身,就是运行态的"安全网"。
五、这张状态机真正解决了什么问题?
- Ability 被杀但状态还能回来
- 前后台切换不抖、不乱
- PC 多窗口下不会双跑逻辑
- 音频 / 输入 / 渲染不会错位
- Debug 时你能说清楚"现在在哪一态"
六、一句掏心窝子的总结
在 HarmonyOS 上,运行态不是"过程",而是"状态"。
想让游戏活得久,先让状态站得住。