工程目录结构说明
约定:
minSdkVersion = 26、targetSdkVersion = 36、JDK 17、仅 Java、不用 Kotlin;Gradle 8.x + AGP 8.x;包名根edu.cdp.android.dayNN。
1. 工程总览
在 Android Studio(AS)里新建 Empty Activity(注意选 Java 而不是 Kotlin)后,工程根目录一眼看上去并不复杂——和早年的 Eclipse 时代相比,已经清爽很多:
记住一条总原则:源码三件套——AndroidManifest.xml + java/ + res/——其他都是装配它们的「脚手架」。
| 区块 | 放什么 | 谁负责 |
|---|---|---|
| 根目录 | Gradle 配置、Wrapper、.gitignore |
项目级,本课基本不动 |
app/ |
应用模块(源码 + 资源 + 清单) | 我们写代码的主战场 |
app/src/main/ |
真正能跑的应用源码 | 业务代码从这里开始 |
gradle/wrapper/ |
Wrapper 配置 | 保证不同机器用同一份 Gradle |
2. 根目录关键文件
2.1 settings.gradle
声明这个工程包含哪些模块。本课只有一个 app:
include ':app' 这一行最常被本课修改——你改名模块就要同时改这里。
2.2 build.gradle(项目级)
放各模块共用的插件声明。本课常见配置:
版本号与 AGP 对应;第一节课用 AS 默认即可,不要主动改。
2.3 app/build.gradle(模块级)
这里的设置最影响 app 行为。要记住的字段:
| 字段 | 本课取值 | 含义 |
|---|---|---|
applicationId |
edu.cdp.android.day01.helloworld |
应用的「身份证」(和包名相似,与 Java 包名可以不同) |
minSdkVersion |
26 |
最低支持到 Android 8.0 |
targetSdkVersion |
36 |
编译时按最新版行为校验 |
compileSdkVersion |
36 |
编译时使用的 SDK 版本 |
versionCode / versionName |
1 / "1.0" |
安装包升级用,本课固定即可 |
sourceCompatibility / targetCompatibility 用 JavaVersion.VERSION_17,对应 JDK 17。
2.4 gradle/wrapper/ 与 gradlew
-
gradlew/gradlew.bat:命令行执行入口。 -
gradle-wrapper.properties:记着「本工程固定用哪一版 Gradle」。
课堂约定:所有人用同一份 Wrapper,保证编译环境一致;遇到「Gradle 版本不匹配」的报错,先检查这台机器是不是用了 Wrapper,而不是全局 gradle。
3. app/ 模块:源码三件套
进入 app/src/main/,目录只有三种东西:清单、Java 代码、资源。
3.1 AndroidManifest.xml(清单)
这是 app「登记」所有组件的地方。 不登记的 Activity,系统不会启动它。
最小化示例(AS 帮我们生成):
要记的几条:
| 元素/属性 | 作用 | 本课是否动 |
|---|---|---|
<uses-permission> |
申请权限(写文件、网络等) | 第 7 日起需要时再加 |
<application android:theme> |
app 主题 | 第 14 日改 NoActionBar |
<activity android:name> |
类名,. 表示「相对 applicationId 的子包」 |
改名时同步改这里 |
<intent-filter> + MAIN / LAUNCHER |
桌面图标点进来的入口 | 一个 app 只配一个 |
3.2 java/:Java 源码
-
路径层次要和包名一一对应: package edu.cdp.android.day01.helloworld;对应java/edu/cdp/android/day01/helloworld/。 -
一个文件一个顶层 public类,文件名必须与类名一致。 -
第 1 日就一个 MainActivity.java,第 4 日起按课程约定的子包结构拆。
3.3 res/:资源
下一节单独讲。
4. res/ 资源子目录
res/ 放 App 资源(图片、布局、文字、主题……)。这些文件会在编译期编入 R.java,运行时用资源 ID(R.string.app_name、R.layout.activity_main)引用——比直接传字符串安全得多。
| 目录 | 放什么 | 备注 |
|---|---|---|
res/layout/ |
布局 XML(activity_main.xml) |
第 2 日开始天天改 |
res/values/ |
strings.xml、colors.xml、styles.xml、themes.xml |
不放文件名当 ID;XML 节点名决定 R 中的字段名 |
res/drawable/ |
位图(PNG/JPEG)、.9.png、Shape、Selector |
第 2 日开始大量使用 Shape/Selector |
res/mipmap-*dpi/ |
应用图标(多分辨率) | AS 默认生成,不要手动改文件名 |
res/menu/ |
菜单 XML(Toolbar 用) | 第 14 日起 |
res/anim/ |
动画 XML(淡入、旋转、补间) | 第 16 日旋转动画 |
res/xml/ |
杂项配置(backup_rules.xml、network_security_config.xml 等) |
本课几乎不动 |
判断资源放哪儿的捷径:
-
要在代码里用资源 ID 拿的(如 findViewById、setBackgroundResource) → 放res/。 -
要保留原文件名 / 目录层级当字面路径读的 → 放 assets/。
5. assets/ 与res/raw/ 怎么选
这是初学者最容易混的一组——它们都能塞「原文件」,区别只在访问方式。
| 维度 | res/raw/ |
assets/ |
|---|---|---|
是否进入 R.java |
✅ 是,用 R.raw.bg 引用 |
❌ 否 |
| 文件名是否保留原样 | 文件名就是 R 里的字段名(如 R.raw.song) |
保留原文件名 + 目录结构 |
| 访问 API | Resources.openRawResource(R.raw.x) |
AssetManager.open("sub/x.mp3") |
| 适用场景 | MediaPlayer 播一段 ogg、铃声;少量固定文件 | 整个 mp3 目录、HTML 模板、JSON 配置目录 |
一句话:用「资源 ID」引,放 raw/;用「路径」读,放 assets/。
例:第 17 日做 JSON 模拟网络列表,可以把 songs.json 放 assets/sample/,代码里这样读:
注意 try / catch / finally 里显式关流——本课禁止 try-with-resources。
6. 课程约定的 Java 子包结构
按课程大纲 2.3 节:「能按职责把源码放到 ui / adapter / model / util / db / listener / service 等子包,根包名仍用 edu.cdp.android.dayNN。」
第 1 日就是 MainActivity 一个文件,没必要拆;从第 4 日起按这套约定分包。例如第 14 日音乐项目:
约定只有三条:
-
Activity 类放在根包(方便 Manifest 用 .MainActivity这种短名字引到)。 -
具名监听器统一放 listener/(独立类或 Activity 内部具名类;本课前面日子用内部具名类也可以,但归在listener/子包里更整齐)。 -
同职责的东西相邻(DAO 放 db/、工具放util/、业务模型放model/),不要随手丢在根包。
一句话总结: 根目录管 Gradle;
app/src/main/里只有清单、Java、资源三件套;资源能进R的放res,要按路径读原文件的放assets;业务代码按ui / adapter / model / util / db / listener / service分子包,根包仍是edu.cdp.android.dayNN。
转载请注明来源:工程目录结构说明







