1、Android开发基础
1.1 App的工程结构
1.1.1 目录结构
App的工程分为两个层次:第一层次是项目,第二层次是模块;每个项目必须有一个模块。
创建一个新的项目后会有两部分:一个默认的模块app,一个Gradle Scripts。开发过程中 "编译运行" 是指编译运行某个模块。
开发者可以根据项目需要在项目中创建多个模块。
app模块
下有三个子目录:
- manifests:下面有一个AndroidManifest.xml文件,存放App的运行配置文件。可以在该文件中配置App的入口页面。
- Java:下面存放三个同名的子包,其中不带 "test" 和 "androidTest" 字样的用来存放此模块的Java代码,其余两个包存放测试用的Java代码。
- res:存放当前模块的资源文件,包括布局资源,图标资源等等。具体如下:
- drawable:存放图形描述文件和图片文件。
- layout:存放App界面布局文件(.xml)。
- mipmap:存放App的启动图标。
- values:存放常量定义文件,例如字符串常量文件string.xml、像素常量文件dimens.xml、颜色常量文件colors.xml、样式风格定义文件styles.xml。
Gradle Scripts
主要存放编译配置文件,具体内容如下:
- build.gradle:分为项目级和模块级。用于指定编译使用的SDK版本和App编译的依赖等信息。
- proguard-rules.pro:描述Java代码的混淆规则。
- gradle.properties:用于配置编译工程的命令行参数,一般不需要改动。
- settings.gradle:配置了需要编译的模块,初始时只有 include:'app' ,另外配置项目的 repositories 也是在此文件中。
- local.properties:项目的本地配置文件,在工程编译时自动生成,用于描述开发者计算机的环境配置,包括本地SDK地址,NDK地址等信息。
1.1.2 编译配置文件
由于 Android Studio (AS)采用 Gradle 完成编译构建操作,因此编译配置文件以 .gradle 为后缀。AS 中在菜单页依次点击File->Project Structure->Project 可以设置 Gradle 的版本。
注意每个版本的 AS 都有对应的 Gradle 版本,只有版本对应才能够编译成功。版本对照关系参考网站:developer.android.google.cn/studio/rele…
在 AS 4.2 之前的版本中,项目级别的 build.gradle 中指定了当亲项目的总体编译规则,可以在此文件中找到 repositories 和 dependencies 节点。
其中 repositories 设置AS插件的网络仓库地址;dependencies 用于设置 gradle 插件的版本号。
从AS Bumblebee(开始),项目级别的 build.gradle 不再存放网络仓库地址,而是配置到了 settings.gradle 中。开发者可以通过以下代码设置阿里云仓库地址:
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
// 以下四行添加阿里云的仓库地址,方便国内开发者下载相关插件
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'}
// 以下添加华为的仓库地址,引入HMS需要
maven { url 'https://developer.huawei.com/repo/'}
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
// 以下四行添加阿里云的仓库地址,方便国内开发者下载相关插件
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'}
// 以下添加华为的仓库地址,引入HMS需要
maven { url 'https://developer.huawei.com/repo/'}
}
}
模块级别的 build.gradle 对应具体模块,指定当前模块的详细编译规则。具体注释如下,代码来自《Android Studio开发实战 从零基础到App上线》-欧阳燊(shēn)。
plugins {
id 'com.android.application'
}
android {
// 指定编译用的SDK版本号。比如31表示使用Android 12编译
compileSdk 31
defaultConfig {
// 指定该模块的应用编号,也就是App的包名
applicationId "com.example.chapter02"
// 指定App适合运行的最小SDK版本号。比如21表示至少要在Android 5.0上运行
minSdk 21
// 指定目标设备的SDK版本号。表示App最希望在哪个版本的Android上运行
targetSdk 31
// 指定App的应用版本号
versionCode 1
// 指定App的应用版本名称
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
// 指定App编译的依赖信息
dependencies {
// 指定引用jar包的路径
implementation fileTree(dir: 'libs', include: ['*.jar'])
// 指定编译Android的高版本支持库。如AppCompatActivity必须指定编译appcompat库
//appcompat库各版本见 https://mvnrepository.com/artifact/androidx.appcompat/appcompat
implementation 'androidx.appcompat:appcompat:1.4.1'
// 指定单元测试编译用的junit版本号
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
1.1.3 运行配置文件AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<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.AS30"
tools:targetApi="31">
<activity
android:name=".activity_scroll_view"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activity_grid_layout"
android:exported="false">
</activity>
<activity
android:name=".activity_relative_layout"
android:exported="false">
</activity>
</application>
</manifest>
上述文件根节点为manifest,package属性制定了该App的包名,manifest 下的 application 节点,各属性描述如下:
- android:allowBackup:是否允许备份。
- android:icon:指定App在手机屏幕上显示的图标。
- android:label:指定App在手机屏幕上显示的名称。
- android:roundIcon:指定App的圆角图标。
- android:supportsRtl:是否支持阿拉伯语/波斯语这种从右往左的文字排列顺序。
- android:theme:指定App的显示风格。
application节点下还有activity节点,它是活动页面的注册声明,只有在 AndroidManifest.xml 中正确配置了activity节点,才能在运行时方文对应的活动页面。当在某个activity节点中配置了以下过滤信息后,此activity则为App主页:
<intent-filter>
<!-- action表明该页面是App的入口页面 -->
<action android:name="android.intent.action.MAIN" />
<!-- category表示是否在手机桌面显示App图标,当有两个activity都设置此标签,
那么桌面就会显示两个App图标 -->
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
注意任意组件节点(activity、receiver、service)一旦配置了intent-filter,那么该组件节点就必须声明android:exported属性,以便设定是否支持其他应用调用当前组件。