本专栏文章
上一篇
Android开发修炼之路——(一)Android App开发基础-1
2 App的工程结构
本节介绍App工程的基本结构及其常用配置,首先描述项目和模块的区别,以及工程内部各目录与配置文件的用途说明;其次阐述两种级别的编译配置文件build.gradle,以及它们内部的配置信息说明;再次讲述运行配置文件AndroidManifest.xml的节点信息及其属性说明。
2.1 App工程目录结构
App工程分为两个层次,第一个层次是项目,依次选择菜单File→New→New Project即可创建新项目。另一个层次是模块,模块依附于项目,每个项目至少有一个模块,也能拥有多个模块,依次选择菜单File→New→New Module即可在当前项目创建新模块。
一般所言的“编译运行App”,指的是运行某个模块,而非运行某个项目,因为模块才对应实际的App。单击Android Studio左上角竖排的Project标签,可见App工程的项目结构如图所示。
从图中看到,该项目下面有两个分类:一个是app(代表app模块);另一个是Gradle Scripts。其
中,app下面又有3个子目录,其功能说明如下:
(1)manifests子目录,下面只有一个XML文件,即AndroidManifest.xml,它是App的运行配置文
件。
(2)java子目录,下面有3个com.example.myapp包,其中第一个包存放当前模块的Java源代码,后面两个包存放测试用的Java代码。
(3)res子目录,存放当前模块的资源文件。res下面又有4个子目录:
- drawable目录存放图形描述文件与图片文件。
- layout目录存放App页面的布局文件。
- mipmap目录存放App的启动图标。
- values目录存放一些常量定义文件,例如字符串常量strings.xml、像素常量dimens.xml、颜色常量colors.xml、样式风格定义styles.xml等。
Gradle Scripts下面主要是工程的编译配置文件,主要有:
(1)build.gradle,该文件分为项目级与模块级两种,用于描述App工程的编译规则。
(2)proguard-rules.pro,该文件用于描述Java代码的混淆规则。
(3)gradle.properties,该文件用于配置编译工程的命令行参数,一般无须改动。
(4)settings.gradle,该文件配置了需要编译哪些模块。初始内容为include ‘:app’,表示只编译app模块。
(5)local.properties,项目的本地配置文件,它在工程编译时自动生成,用于描述开发者电脑的环境配置,包括SDK的本地路径、NDK的本地路径等。
2.2 编译配置文件build.gradle
新创建的App项目默认有两个build.gradle,一个是Project项目级别的build.gradle;另一个是Module模块级别的build.gradle。
项目级别的build.gradle指定了当前项目的总体编译规则,打开该文件在buildscript下面找到
repositories和dependencies两个节点,其中repositories节点用于设置Android Studio插件的网络仓库地址,而dependencies节点用于设置gradle插件的版本号。由于官方的谷歌仓库位于国外,下载速度相对较慢,因此可在repositories节点添加阿里云的仓库地址,方便国内开发者下载相关插件。修改之后的buildscript节点内容如下所示
buildscript {
repositories {
// 以下四行添加阿里云的仓库地址,方便国内开发者下载相关插件
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://maven.aliyun.com/repository/google'}
maven { url 'https://maven.aliyun.com/repository/gradle-plugin'}
maven { url 'https://maven.aliyun.com/repository/public'}
google()
jcenter()
}
dependencies {
// 配置gradle插件版本,下面的版本号就是Android Studio的版本号
classpath 'com.android.tools.build:gradle:4.1.0'
}
}
模块级别的build.gradle对应于具体模块,每个模块都有自己的build.gradle,它指定了当前模块的详细编译规则。下面给模块的build.gradle补充文字注释,方便读者更好地理解每个参数的用途。
plugins {
id("com.android.application")
}
android {
namespace = "com.example.myapplication" // 设置Android命名空间
compileSdk = 34 // 设置编译使用的SDK版本
defaultConfig {
applicationId = "com.example.myapplication" // 设置应用的包名
minSdk = 24 // 设置应用的最低支持版本
targetSdk = 34 // 设置应用的目标支持版本
versionCode = 1 // 设置应用的版本号(用于标识版本)
versionName = "1.0" // 设置应用的版本名称
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" // 设置测试用例的运行器
}
buildTypes {
release {
isMinifyEnabled = false // 禁用混淆
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") // 配置混淆规则
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8 // 指定源代码兼容的Java版本
targetCompatibility = JavaVersion.VERSION_1_8 // 指定目标代码兼容的Java版本
}
}
dependencies {
implementation("androidx.appcompat:appcompat:1.6.1") // 依赖AppCompatActivity和主题
implementation("com.google.android.material:material:1.9.0") // 依赖Material Design组件
implementation("androidx.constraintlayout:constraintlayout:2.1.4") // 依赖ConstraintLayout布局组件
testImplementation("junit:junit:4.13.2") // 用于单元测试,依赖JUnit框架
androidTestImplementation("androidx.test.ext:junit:1.1.5") // 用于Android单元测试,依赖JUnit扩展库
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") // 用于Android单元测试,依赖Espresso测试框架
}
为啥这两种编译配置文件的扩展名都是Gradle呢?这是因为它们采用了Gradle工具完成编译构建操作。Gradle工具的版本配置在gradle\wrapper\gradle-wrapper.properties,也可以依次选择菜单
File→Project Structure→Project,在弹出的设置页面中修改Gradle Version。注意每个版本的Android Studio都有对应的Gradle版本,只有二者的版本正确对应,App工程才能成功编译。比如Android Studio 4.1对应的Gradle版本为6.5,更多的版本对应关系见https://developer.android.google.cn/studio/releases/gradle-plugin#updating-plugin。
2.3 运行配置文件AndroidManifest.xml
AndroidManifest.xml指定了App的运行配置信息,它是一个XML描述文件,初始内容如下所示:
<?xml version="1.0" encoding="utf-8"?>
<!-- 定义一个AndroidManifest.xml文件,用于描述应用程序的基本属性和配置信息 -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- 应用程序元素,用于定义应用程序的基本属性 -->
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication"
tools:targetApi="31">
<!-- Activity元素,用于定义应用程序中的一个Activity组件 -->
<activity
android:name=".MainActivity"
android:exported="true">
<!-- Intent过滤器元素,用于定义Activity能够响应的Intent过滤条件 -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<!-- 类别元素,用于指定Intent的类别 -->
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
可见AndroidManifest.xml的根节点为manifest,它的package属性指定了该App的包名。manifest下面有个application节点,它的各属性说明如下:
- android:allowBackup,是否允许应用备份。允许用户备份系统应用和第三方应用的apk安装包和应用数据,以便在刷机或者数据丢失后恢复应用,用户即可通过adb backup和adb restore来进行对应用数据的备份和恢复。为true表示允许,为false则表示不允许。
- android:icon,指定App在手机屏幕上显示的图标。
- android:label,指定App在手机屏幕上显示的名称。 android:roundIcon,指定App的圆角图标。
- android:supportsRtl,是否支持阿拉伯语/波斯语这种从右往左的文字排列顺序。为true表示支持,为false则表示不支持。 android:theme,指定App的显示风格。
注意到application下面还有个activity节点,它是活动页面的注册声明,只有在AndroidManifest.xml中正确配置了activity节点,才能在运行时访问对应的活动页面。初始配置的MainActivity正是App的默认主页,之所以说该页面是App主页,是因为它的activity节点内部还配置了以下的过滤信息:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
其中action节点设置的android.intent.action.MAIN表示该页面是App的入口页面,启动App时会最先打开该页面。而category节点设置的android.intent.category.LAUNCHER决定了是否在手机屏幕上显示App图标,如果同时有两个activity节点内部都设置了
android.intent.category.LAUNCHER,那么桌面就会显示两个App图标。以上的两种节点规则可能一开始不太好理解,读者只需记住默认主页必须同时配置这两种过滤规则即可。
本笔记参考于[B站动脑学院],仅作学习用途,方便随时查看。 参考资料:2022 最新 Android 基础教程,从开发入门到项目实战,看它就够了,更新中