"""
🎯 鸿蒙(HarmonyOS)应用资源放置完整指南
===========================================
本指南涵盖 HarmonyOS/OpenHarmony 应用开发中的资源管理和放置规则
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📁 一、资源目录结构
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
HarmonyOS 项目标准目录结构:
MyApplication/
├── entry/ # 主模块
│ └── src/
│ └── main/
│ ├── ets/ # TypeScript/ArkTS代码
│ │ ├── entryability/ # 应用入口
│ │ └── pages/ # 页面
│ ├── resources/ # 资源目录 ⭐
│ │ ├── base/ # 默认资源
│ │ │ ├── element/ # 元素资源
│ │ │ ├── media/ # 媒体资源
│ │ │ └── profile/ # 配置文件
│ │ ├── en_US/ # 英文资源
│ │ ├── zh_CN/ # 中文资源
│ │ ├── rawfile/ # 原始文件
│ │ └── ...
│ └── module.json5 # 模块配置
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📂 二、resources 目录详解
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
base/ 目录 - 默认资源(必需)
├── element/
│ ├── string.json # 字符串资源
│ ├── color.json # 颜色资源
│ ├── float.json # 浮点数资源
│ ├── boolean.json # 布尔值资源
│ ├── intarray.json # 整型数组
│ ├── strarray.json # 字符串数组
│ └── plural.json # 复数资源
│
├── media/ # 媒体资源
│ ├── icon.png # 图标
│ ├── background.jpg # 图片
│ ├── video.mp4 # 视频
│ └── audio.mp3 # 音频
│
└── profile/ # 配置文件
├── main_pages.json # 页面路由
└── form_config.json # 卡片配置限定词目录 - 适配不同场景
├── zh_CN/ # 中文(中国)
├── en_US/ # 英文(美国)
├── dark/ # 深色模式
├── ldpi/ # 低密度屏幕
├── mdpi/ # 中密度屏幕
├── hdpi/ # 高密度屏幕
├── xhdpi/ # 超高密度屏幕
├── xxhdpi/ # 超超高密度屏幕
└── xxxhdpi/ # 超超超高密度屏幕-
rawfile/ 目录 - 原始文件
- 不经过编译处理的原始文件
- 可以是任意格式
- 通过路径直接访问
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎨 三、各类资源详细说明
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- 字符串资源 (element/string.json)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{
"string": [
{
"name": "app_name",
"value": "我的应用"
},
{
"name": "welcome_text",
"value": "欢迎使用"
},
{
"name": "format_string",
"value": "用户: %s, 年龄: %d"
}
]
}
使用方式:
// ArkTS代码
r('app.string.welcome_text')
- 颜色资源 (element/color.json)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{
"color": [
{
"name": "primary_color",
"value": "#007DFF"
},
{
"name": "text_color",
"value": "#182431"
},
{
"name": "background_color",
"value": "#F1F3F5"
}
]
}
使用方式:
Text('Hello')
.fontColor(r('app.color.background_color'))
- 图片资源 (media/)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
支持格式:
- PNG (.png)
- JPEG (.jpg, .jpeg)
- GIF (.gif)
- WebP (.webp)
- SVG (.svg)
放置位置:
src/main/resources/base/media/icon.png
使用方式:
Image($r('app.media.icon'))
.width(100)
.height(100)
- 浮点数资源 (element/float.json)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{
"float": [
{
"name": "font_size_small",
"value": "12fp"
},
{
"name": "font_size_normal",
"value": "16fp"
},
{
"name": "font_size_large",
"value": "20fp"
}
]
}
使用方式:
Text('Hello')
.fontSize($r('app.float.font_size_normal'))
布尔值资源 (element/boolean.json)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{
"boolean": [
{
"name": "is_debug",
"value": true
},
{
"name": "enable_animation",
"value": false
}
]
}数组资源 (element/strarray.json)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{
"strarray": [
{
"name": "week_days",
"value": [
{ "value": "周一" },
{ "value": "周二" },
{ "value": "周三" },
{ "value": "周四" },
{ "value": "周五" },
{ "value": "周六" },
{ "value": "周日" }
]
}
]
}rawfile 原始文件
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
放置位置:
src/main/resources/rawfile/config.json
src/main/resources/rawfile/data/users.txt
src/main/resources/rawfile/fonts/custom_font.ttf
使用方式:
import resourceManager from '@ohos.resourceManager';
// 读取rawfile文件
let context = getContext(this);
context.resourceManager.getRawFileContent('config.json', (error, value) => {
if (error) {
console.error('读取失败');
} else {
let content = String.fromCharCode.apply(null, new Uint8Array(value));
console.info('文件内容:', content);
}
});
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🌍 四、多语言适配
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
目录结构:
resources/
├── base/
│ └── element/
│ └── string.json # 默认语言(备用)
├── zh_CN/ # 简体中文
│ └── element/
│ └── string.json
├── zh_TW/ # 繁体中文
│ └── element/
│ └── string.json
├── en_US/ # 英文
│ └── element/
│ └── string.json
└── ja_JP/ # 日文
└── element/
└── string.json
示例 - base/element/string.json:
{
"string": [
{ "name": "hello", "value": "Hello" },
{ "name": "goodbye", "value": "Goodbye" }
]
}
示例 - zh_CN/element/string.json:
{
"string": [
{ "name": "hello", "value": "你好" },
{ "name": "goodbye", "value": "再见" }
]
}
系统会根据设备语言自动选择对应资源
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📱 五、屏幕密度适配
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
不同屏幕密度放置不同分辨率的图片:
resources/
├── base/
│ └── media/
│ └── icon.png # 默认图片(备用)
├── ldpi/ # 120dpi, 0.75x
│ └── media/
│ └── icon.png # 36x36 (48 * 0.75)
├── mdpi/ # 160dpi, 1x (基准)
│ └── media/
│ └── icon.png # 48x48
├── hdpi/ # 240dpi, 1.5x
│ └── media/
│ └── icon.png # 72x72 (48 * 1.5)
├── xhdpi/ # 320dpi, 2x
│ └── media/
│ └── icon.png # 96x96 (48 * 2)
├── xxhdpi/ # 480dpi, 3x
│ └── media/
│ └── icon.png # 144x144 (48 * 3)
└── xxxhdpi/ # 640dpi, 4x
└── media/
└── icon.png # 192x192 (48 * 4)
系统会根据设备DPI自动选择合适的图片
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎯 六、限定词优先级
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
资源匹配优先级(从高到低):
- 移动国家码和移动网络码 (MCC-MNC)
- 语言_国家 (zh_CN, en_US)
- 语言 (zh, en)
- 屏幕方向 (vertical, horizontal)
- 颜色模式 (dark, light)
- 屏幕密度 (ldpi, mdpi, hdpi...)
- base (默认)
组合限定词示例:
resources/
├── base/
├── zh_CN/
├── zh_CN-dark/ # 中文+深色模式
├── zh_CN-dark-vertical/ # 中文+深色+竖屏
└── en_US-horizontal/ # 英文+横屏
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
💻 七、代码中访问资源
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- 在ArkTS中访问资源
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 字符串
Text($r('app.string.hello'))
// 颜色
.fontColor($r('app.color.primary_color'))
// 图片
Image($r('app.media.icon'))
// 浮点数
.fontSize($r('app.float.font_size_normal'))
// 格式化字符串
let name = "张三";
let age = 25;
// 如果string.json中定义: "user_info": "姓名: %s, 年龄: %d"
Text($r('app.string.user_info', name, age))
- 通过ResourceManager访问
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
import resourceManager from '@ohos.resourceManager';
@Entry
@Component
struct Index {
private resMgr: resourceManager.ResourceManager;
aboutToAppear() {
this.resMgr = getContext(this).resourceManager;
// 获取字符串
this.resMgr.getStringValue($r('app.string.hello').id, (error, value) => {
console.info('字符串:', value);
});
// 获取颜色
this.resMgr.getNumber($r('app.color.primary_color').id, (error, value) => {
console.info('颜色值:', value);
});
// 读取rawfile
this.resMgr.getRawFileContent('config.json', (error, value) => {
let content = String.fromCharCode.apply(null, new Uint8Array(value));
console.info('文件内容:', content);
});
}
build() {
// UI代码
}
}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎨 八、图标和启动页
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- 应用图标
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
位置: src/main/resources/base/media/app_icon.png
尺寸要求:
- 建议尺寸: 256x256 像素
- 格式: PNG (支持透明)
配置文件 (module.json5):
{
"module": {
"abilities": [
{
"icon": "string:app_name"
}
]
}
}
- 启动页(Splash Screen)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
位置: src/main/resources/base/media/startIcon.png
配置 (module.json5):
{
"module": {
"abilities": [
{
"startWindowIcon": "color:start_window_background"
}
]
}
}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠️ 九、注意事项和最佳实践
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
资源命名规范
✅ 使用小写字母和下划线: icon_home.png
✅ 见名知意: button_submit, color_primary
❌ 避免: Icon.png, btnSubmit.png-
图片资源优化
- PNG: 适合有透明背景的图标
- JPEG: 适合照片类图片
- WebP: 更小的文件体积
- SVG: 矢量图,适合图标
-
多语言文本
- base/ 必须提供默认文本
- 避免硬编码文本
- 注意文本长度变化
-
文件大小
- 单个图片不超过 1MB
- 总资源包不超过 100MB
- 考虑使用网络加载大文件
-
rawfile 使用场景
- 配置文件 (JSON, XML)
- 自定义字体
- 证书文件
- 数据库文件
- 不需要编译的原始文件
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📝 十、完整示例
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
项目结构:
MyApp/
└── entry/
└── src/
└── main/
├── ets/
│ └── pages/
│ └── Index.ets
└── resources/
├── base/
│ ├── element/
│ │ ├── string.json
│ │ ├── color.json
│ │ └── float.json
│ ├── media/
│ │ ├── app_icon.png
│ │ └── background.jpg
│ └── profile/
│ └── main_pages.json
├── zh_CN/
│ └── element/
│ └── string.json
├── en_US/
│ └── element/
│ └── string.json
└── rawfile/
└── config.json
string.json (base):
{
"string": [
{ "name": "app_name", "value": "My App" },
{ "name": "welcome", "value": "Welcome" }
]
}
string.json (zh_CN):
{
"string": [
{ "name": "app_name", "value": "我的应用" },
{ "name": "welcome", "value": "欢迎" }
]
}
color.json:
{
"color": [
{ "name": "primary", "value": "#007DFF" },
{ "name": "background", "value": "#F1F3F5" }
]
}
Index.ets:
@Entry
@Component
struct Index {
build() {
Column() {
Image($r('app.media.app_icon'))
.width(100)
.height(100)
Text($r('app.string.welcome'))
.fontSize($r('app.float.title_size'))
.fontColor($r('app.color.primary'))
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.background'))
}
}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔗 参考资源
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
官方文档:
- HarmonyOS开发文档: https://developer.harmonyos.com/
- 资源分类与访问: https://developer.harmonyos.com/cn/docs/documentation/doc-guides/resource-categories-and-access
- OpenHarmony文档: https://docs.openharmony.cn/
工具:
- DevEco Studio: 官方IDE
- 资源预览器: IDE内置
- 图标生成器: 在线工具
社区:
- 鸿蒙开发者论坛
- HarmonyOS技术社区
- OpenAtom开源基金会
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
总结:
- 资源必须放在 resources/ 目录下
- base/ 是默认资源,必须提供
- 使用限定词目录实现多语言、多分辨率适配
- 通过 $r() 语法访问资源
- rawfile/ 存放不需要编译的原始文件
- 遵循命名规范,优化资源大小
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
"""
print(doc)