
网罗开发 (小红书、快手、视频号同名)
大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。
图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG
我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验 。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。
展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索"展菲",即可纵览我在各大平台的知识足迹。
📣 每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
文章目录
-
- 引言
- 一、先说结论
- 二、最常见的错误写法
-
- [直接在 UI 用资源](#直接在 UI 用资源)
- 随用随加载
- 三、正确思路:资源也是"状态"
- [四、第一步:设计 ResourceManager](#四、第一步:设计 ResourceManager)
- 五、第二步:资源预加载
- 六、第三步:资源分级
- [七、第四步:结合 Store](#七、第四步:结合 Store)
-
- 示例
- [UI 控制](#UI 控制)
- 八、第五步:多端资源管理
- 九、第六步:支持网络资源
-
- 场景
- [ResourceManager 扩展](#ResourceManager 扩展)
- 十、第七步:释放资源
- 十一、完整资源架构
- 十二、常见错误
- 总结
引言
很多人在做鸿蒙游戏时,一开始对"资源加载"不太在意:
图片 → 直接用
音频 → 直接播
配置 → 写死
Demo 阶段完全没问题。但只要项目一变大,很快就会遇到:
- 图片加载卡顿
- 首屏白屏
- 内存飙升
- 多端资源不一致
- 热更新困难
最后你会发现:
游戏卡不卡,不只是性能问题,而是资源管理问题。
在 HarmonyOS 的游戏架构中:
资源加载,不是"读文件",而是"系统设计"。
一、先说结论
一个成熟的资源系统,必须解决 4 件事:
1、什么时候加载(时机)
2、从哪里加载(来源)
3、加载到哪里(缓存)
4、谁来管理(统一入口)
如果缺一个:
要么卡顿,要么崩溃,要么不可扩展
二、最常见的错误写法
直接在 UI 用资源
ts
Image("images/player.png")
问题:
- 每次渲染都可能触发加载
- 无缓存控制
- 无法统一管理
随用随加载
ts
const img = await loadImage("enemy.png")
问题:
- 重复加载
- 性能不可控
- 无法多端复用
本质问题:
资源没有"生命周期管理"
三、正确思路:资源也是"状态"
在鸿蒙游戏中,资源不应该是"随便用的文件",而是:
受控的数据
正确模型:
ResourceManager(资源管理器)
↓
Cache(缓存)
↓
UI / Game 使用
四、第一步:设计 ResourceManager
基础实现
ts
// resource/ResourceManager.ets
export class ResourceManager {
private imageCache: Map<string, any> = new Map()
async loadImage(path: string) {
if (this.imageCache.has(path)) {
return this.imageCache.get(path)
}
const img = await this.fetchImage(path)
this.imageCache.set(path, img)
return img
}
async fetchImage(path: string) {
// 实际加载逻辑(可扩展)
return path
}
}
export const resourceManager = new ResourceManager()
核心能力:
- 缓存
- 统一入口
- 可扩展
五、第二步:资源预加载
错误:进入页面才加载
会卡顿。
正确:提前加载
ts
async preload() {
await Promise.all([
resourceManager.loadImage("player.png"),
resourceManager.loadImage("enemy.png"),
resourceManager.loadImage("bg.png")
])
}
页面入口
ts
aboutToAppear() {
this.init()
}
async init() {
await preload()
this.ready = true
}
配合 loading UI:
加载完成 → 渲染游戏
六、第三步:资源分级
不是所有资源都要一起加载。
推荐分级:
核心资源(启动必须)
↓
场景资源(进入场景)
↓
动态资源(运行时加载)
示例
ts
// 核心
load("ui.png")
// 场景
load("level1_bg.png")
// 动态
load("boss.png")
好处:
- 首屏快
- 内存可控
- 体验更好
七、第四步:结合 Store
资源加载状态,也应该进 Store。
示例
ts
gameStore.dispatch({
type: 'RESOURCE_LOADING'
})
ts
case 'RESOURCE_LOADED':
state.ready = true
UI 控制
ts
if (!this.state.ready) {
Text("Loading...")
} else {
GameView()
}
本质:
资源加载也是数据流的一部分
八、第五步:多端资源管理
问题
不同设备:
手机 / TV / 平板
分辨率不同,资源不同。
方案:资源适配
ts
getResource(path: string) {
if (device.type === 'tv') {
return `tv/${path}`
}
return `mobile/${path}`
}
或:
assets/
├─ mdpi
├─ hdpi
├─ xhdpi
本质:
资源要"适配设备",而不是通用一份
九、第六步:支持网络资源
场景
游戏更新资源,不发新版本。
ResourceManager 扩展
ts
async fetchImage(path: string) {
const local = await this.tryLocal(path)
if (local) return local
return await fetch(`https://cdn.xxx.com/${path}`)
}
好处:
- 热更新
- 动态资源
- 降低包体
十、第七步:释放资源
常见问题
资源一直缓存,不释放。
解决方案
ts
release(path: string) {
this.imageCache.delete(path)
}
场景切换
ts
onLeaveScene() {
resourceManager.release("level1_bg.png")
}
本质:
资源要有"生命周期"
十一、完整资源架构
Game
↓
ResourceManager
↓
Cache
↓
Local / Network
扩展:
ResourceManager
├─ Image
├─ Audio
├─ Config
十二、常见错误
1、UI 直接加载资源:不可控。
2、不做缓存:性能崩。
3、一次加载全部资源:内存炸。
4、不区分设备:显示异常。
5、不支持网络资源:无法扩展。
总结
鸿蒙游戏资源加载与管理的核心:
ResourceManager(统一入口)
+ Cache(缓存)
+ Preload(预加载)
+ 分级加载
+ 多端适配
+ 生命周期管理
在 HarmonyOS 中,这套设计带来的不是"性能优化",而是:
从"加载资源",升级为"管理资源系统"。
最后:
资源管理做不好,游戏一定卡;做得好,体验直接拉开差距。