3、项目结构搭建:创建HarmonyOS项目、配置module.json5、理解资源目录结构

好,咱们正式开始动手了。这一章我带你走一遍项目搭建的全流程。说实话,很多新手一上来就急着写代码,结果项目结构乱成一锅粥,后面改起来想死的心都有。我个人习惯是,先把架子搭稳了,再往里填东西。

3.1 创建HarmonyOS项目

打开DevEco Studio,这个IDE你应该已经装好了吧?没装的话先去华为开发者官网下载,记得选对版本——我吃过这个亏,装了个旧版,结果API对不上,折腾了半天。

创建项目的步骤很简单:

  1. 点击「Create Project」
  2. 选择模板——咱们做多媒体播放器,选「Empty Ability」就行
  3. 配置项目信息:
字段 填写内容 说明
Project Name MediaPlayerDemo 项目名,别用中文
Bundle Name com.example.mediaplayer 包名,反向域名格式
Save Location 默认或自定义 找个好找的目录
Compatible SDK API 9 或更高 建议选最新稳定版
Device Type Phone 咱们先做手机端

点击Finish,等它同步完依赖。嗯,这里要注意:第一次创建项目可能会下载一些SDK组件,网速慢的话得等几分钟。别急,喝杯咖啡的功夫。

3.2 配置module.json5

项目创建好后,你会看到 entry/src/main/module.json5 这个文件。它相当于应用的「身份证」,所有关键配置都写在这里。我刚开始接触鸿蒙时,总觉得这文件可有可无,直到有一次打包死活过不了,才发现是这里漏配了权限。

咱们的多媒体播放器需要几个关键配置,我直接给你看最终版本:

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "MainAbility",
    "deviceTypes": ["phone"],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "abilities": [
      {
        "name": "MainAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ts",
        "description": "$string:entryability_desc",
        "icon": "$media:icon",
        "label": "$string:entryability_label",
        "startWindowIcon": "$media:icon",
        "startWindowBackground": "$color:start_window_background",
        "visible": true,
        "skills": [
          {
            "actions": ["action.system.home"],
            "entities": ["entity.system.home"]
          }
        ]
      }
    ],
    "requestPermissions": [
      {
        "name": "ohos.permission.READ_MEDIA"
      },
      {
        "name": "ohos.permission.WRITE_MEDIA"
      },
      {
        "name": "ohos.permission.INTERNET"
      }
    ]
  }
}

看到 requestPermissions 那块了吗?这三个权限是播放器的命根子:

  • READ_MEDIA:读取本地媒体文件
  • WRITE_MEDIA:写入媒体文件(比如下载缓存)
  • INTERNET:网络播放必备

⚠️ 我曾经踩过的坑:有次忘了配READ_MEDIA权限,结果在真机上运行时,文件选择器一片空白。查了半天才发现是权限没申请。记住,模拟器上可能不报错,但真机一定会卡你。

3.3 理解资源目录结构

打开 entry/src/main/resources 目录,你会看到一堆文件夹。别慌,我来给你捋一捋。

资源目录的结构是这样的:

resources/
├── base/
│   ├── element/
│   │   ├── string.json      // 字符串资源
│   │   ├── color.json       // 颜色定义
│   │   └── float.json       // 浮点数值
│   ├── media/               // 图片、音频等媒体文件
│   │   └── icon.png
│   ├── profile/             // 配置文件
│   │   └── main_pages.json  // 页面路由配置
│   └── layout/              // 布局文件(XML方式)
├── en_US/                   // 英文资源
├── zh_CN/                   // 中文资源
└── rawfile/                 // 原始文件,不经过编译

这里我重点说几个:

3.3.1 element目录——你的「变量仓库」

我个人习惯把所有可变的文本、颜色、尺寸都放到这里。比如:

// string.json
{
  "string": [
    {"name": "app_name", "value": "媒体播放器"},
    {"name": "play_button", "value": "播放"},
    {"name": "pause_button", "value": "暂停"}
  ]
}

// color.json
{
  "color": [
    {"name": "primary_color", "value": "#FF007AFF"},
    {"name": "background_color", "value": "#FF1C1C1E"}
  ]
}

为什么要这么做?你想想看,如果哪天产品经理说「把主色调从蓝色改成红色」,你只需要改一个地方。要是硬编码在代码里,那得翻遍所有页面——我经历过,真的会崩溃。

3.3.2 media目录——放你的素材

图标、启动图、默认封面图都放这里。注意,音频文件别放这里——它会被编译压缩,影响性能。音频应该放到 rawfile 目录。

3.3.3 rawfile目录——放「原汁原味」的文件

这个目录下的文件不会被编译,保持原始格式。咱们的播放器会用到:

  • 测试用的MP3文件
  • 歌词LRC文件
  • 视频字幕文件

💡 小技巧:在rawfile里放一个测试音频文件,开发调试时直接用,省得每次都要从手机里选文件。我一般放一个30秒的测试曲,够用了。

3.3.4 main_pages.json——页面路由

这个文件定义了应用的页面结构:

{
  "src": [
    "pages/Index",
    "pages/PlayerPage",
    "pages/PlaylistPage"
  ]
}

每加一个新页面,都要在这里注册。忘了的话,运行时直接白屏——别问我怎么知道的。

3.4 项目结构的最佳实践

最后,分享一个我自己的项目组织习惯。在 ets 目录下,我会这样分:

ets/
├── entryability/       // Ability生命周期
├── pages/              // 页面文件
│   ├── Index.ets       // 首页
│   ├── PlayerPage.ets  // 播放器页面
│   └── PlaylistPage.ets// 播放列表页面
├── model/              // 数据模型
│   └── SongModel.ets
├── service/            // 业务逻辑
│   └── PlayerService.ets
└── common/             // 公共组件
    └── MusicControl.ets

说白了,就是按功能模块分文件夹。别把所有代码都塞到一个文件里,那叫「屎山代码」。我接手过这样的项目,改一个bug要翻3000行代码,那感觉……嗯,你懂的。

好了,项目结构就搭到这。下一章咱们开始写真正的播放器逻辑,到时候你会感谢现在把结构理清楚的自己。