第2章:Android项目结构解析
说实话,很多初学者拿到一个Android项目,第一反应就是懵。文件夹一堆,文件一堆,到底哪个是干嘛的?我当年刚入行时也是这样,打开Android Studio新建项目,看着满屏的目录结构,心里直打鼓。今天我就带你把这些东西捋清楚。
2.1 项目目录结构
一个标准的Android项目,大致长这样:
MyApplication/
├── app/
│ ├── src/
│ │ ├── main/
│ │ │ ├── java/com/example/myapp/
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── ...
│ │ │ ├── res/
│ │ │ │ ├── layout/
│ │ │ │ ├── drawable/
│ │ │ │ ├── values/
│ │ │ │ └── ...
│ │ │ └── AndroidManifest.xml
│ │ ├── test/
│ │ └── androidTest/
│ ├── build.gradle
│ └── ...
├── gradle/
├── build.gradle
├── settings.gradle
└── gradle.properties
嗯,看着挺多,但核心就几个部分。我习惯把项目结构分成三层来理解:
- 项目根目录:负责全局配置,比如Gradle版本、仓库地址
- app模块:你的代码、资源、清单文件全在这
- Gradle相关:构建脚本,控制编译、打包、依赖
你想想看,app模块才是我们真正干活的地方。其他那些gradle文件,说白了就是告诉系统「怎么编译这个app」。
重点:src/main/java 放Java/Kotlin代码,src/main/res 放资源文件,AndroidManifest.xml 是应用的「身份证」。
2.2 Gradle构建系统
Gradle这东西,我第一次接触时也觉得挺玄乎。后来发现,它就是个自动化构建工具。你写代码,它帮你编译、打包、签名、生成APK。
项目中至少有两个build.gradle文件:
项目级build.gradle(根目录):
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.0"
}
}
模块级build.gradle(app目录):
plugins {
id 'com.android.application'
}
android {
compileSdk 33
defaultConfig {
applicationId "com.example.myapp"
minSdk 21
targetSdk 33
versionCode 1
versionName "1.0"
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.6.0'
implementation 'com.google.android.material:material:1.8.0'
}
我个人习惯把依赖版本号抽出来,放到一个单独的gradle文件中管理。这样多个模块共享依赖时,改一处就行。曾经有个项目,因为依赖版本不一致,折腾了我整整一个下午。
小技巧:minSdk 和 targetSdk 这两个值要慎重。minSdk 设得太高,用户少;设得太低,你得兼容老版本的各种坑。我一般建议 minSdk 设为 21,覆盖了95%以上的设备。
2.3 AndroidManifest.xml详解
这个文件,我称之为「应用的户口本」。系统启动你的app前,先读这个文件,看看你有哪些组件、需要什么权限。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.MyApplication">
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
这里有几个关键点:
- package:应用的唯一标识,发布后不能改
- uses-permission:声明需要的权限,比如网络、相机
- activity:注册Activity组件,intent-filter指定入口
- exported:这个属性在Android 12之后必须显式声明
我曾经踩过一个坑:忘记在Manifest里注册Activity,结果运行时直接崩溃。系统提示「ActivityNotFoundException」,当时找了半天才反应过来。嗯,这种低级错误,犯过一次就记住了。
注意:Android 12(API 31)开始,如果Activity包含intent-filter,exported必须设为true。否则系统会拒绝启动这个Activity。
2.4 资源文件管理
资源文件放在res目录下,系统会根据文件名和目录名自动生成R.id、R.layout等引用。说白了,你写代码时用的那些R.xxx,都是从这里来的。
| 目录 | 用途 | 常见文件 |
|---|---|---|
| res/layout | 界面布局 | activity_main.xml |
| res/drawable | 图片、形状 | ic_launcher.png |
| res/values | 字符串、颜色、主题 | strings.xml, colors.xml |
| res/mipmap | 应用图标 | ic_launcher.webp |
| res/menu | 菜单布局 | main_menu.xml |
资源文件有个好处:支持多屏幕适配。比如你在res/layout-sw600dp下放一个布局,系统在平板设备上会自动加载这个布局。我做过一个项目,手机和平板共用一套代码,就是靠这种资源限定符实现的。
另外,字符串资源一定要写在strings.xml里,不要硬编码在Java代码中。为什么?因为后续做国际化时,你只需要添加对应的values-zh、values-en目录就行了。硬编码的话,改起来能让你怀疑人生。
最佳实践:所有文本、颜色、尺寸都定义在res/values中。代码里只引用R.string.xxx、R.color.xxx。这样后期维护、换肤、国际化都方便。
好了,项目结构这块就讲这么多。你只要记住:代码在java目录,资源在res目录,配置在Manifest和Gradle里。这三块搞明白了,Android项目对你来说就没啥秘密了。