Gradle自学 —— 起步
Building Android Apps Sample (gradle.org)
配置 build | Android 开发者 | Android Developers (google.cn)
开发Android应用的时候,Gradle
总是很难不引起我们的注意,在项目达到一定级别之后,对于Gradle
的恰当使用可以让项目更加灵活易用
1. Android项目的构建流程
附上一张Android官方的应用构建流程图
- 首先,编写的项目代码、资源文件、aidl接口、其他的依赖最终会统一通过编译器先转换为.class文件,然后再次由Dex工具编译成.dex文件
- 打包器将资源文件和.dex文件统一打包,生成.apk文件
- 然后对应的KeyStore对.apk文件进行签名
- 如果是Release KeyStore,会使用zipalign工具进行apk对齐优化,减少运行时的内存开销
2. 项目默认生成的配置文件
项目创建之初,Android Studio会创建一系列Gradle
的配置文件,并且预设一些默认配置 这些配置文件通过Groovy
进行编写,包含DSL
元素配置,降低了使用门槛 一些配置文件对应于项目标准,在自定义之前,首先需要了解这些预设的文件在项目中所扮演的角色,新创建的项目中主要有以下Gradle
相关文件
2.1. Gradle设置文件(settings.gradle)
该文件正好对应于上图的第三部分的settings.gradle
位置:项目的根目录下
作用:定义项目级的代码库设置,在构建时决定包含哪些模块
// 该块定义查找和下载插件的存储库
pluginManagement {
repositories {
gradlePluginPortal() // gradle插件门户
google() // 谷歌Maven仓库
mavenCentral() // Maven中央仓库
}
}
// 该块定项目默认使用的仓库依赖,应当在模块级build.gradle中进一步指定
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "GradleDemo"
include ':app'
2.2. 顶层build文件
即第三个框中的build.gradle
文件
位置:项目根目录下
作用:用于定义适用于项目中所有模块的依赖项
// 定义项目中所有模块共用的Gradle依赖项
plugins {
// apply false 不直接应用于当前项目,提供给子模块使用
id 'com.android.application' version '7.2.0' apply false
id 'com.android.library' version '7.2.0' apply false
id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
}
// 用于清理build目录
task clean(type: Delete) {
delete rootProject.buildDir
}
现在许多的Android应用的功能达到一定的量级之后会进行多模块的拆分,在这样的应用场景下,会需要在模块间进行一些属性的共享,方便于进行全局的管理和配置
比如说我想要在子级模块中使用这个依赖统一的版本,方便管理,不需要每个模块下更改 那么,进到顶层build.gradle
,加一个ext
块,将版本用一个变量表示
ext {
versionKtx = '1.7.0' // 指定版本,可以统一修改
}
随后,回到子模块下,找到对应的build.gradle
,使其指向顶层(即rootProject
)build.gradle
中的版本
使用
${}
进行插值时注意把包裹的单引号改为双引号,单引号不支持插值
2.3. 模块级build文件
也就是模块级的build.gradle
,对应于之前第一个红框
位置:<项目>/<模块>/
下,对应每个模块会有一个
作用:为所在模块进行一些配置,可对清单文件和顶层build.gradle
中的一些配置进行覆盖
plugins { // 取自于顶层build文件的插件版本,应用于当前模块
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
// 用于指定所有Android相关的构建配置
android {
compileSdk 32 // 编译版本要求<=该版本
defaultConfig { // 默认配置,可以覆盖对应清单文件
applicationId "com.minos.gradledemo" // 发布唯一标识符,应当保持命名空间与appId一致
minSdk 21 // 可以运行的最小版本
targetSdk 32 // 用于测试的版本
versionCode 1 // app版本号
versionName "1.0" // 用户友好的版本名
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
// 用于配置多种构建类型,构建系统默认定义2种,即debug和release
buildTypes {
// debug并未显示,但是会应用对应debug签名
// release默认应用proguard,不签名
release {
minifyEnabled false // 代码收缩未开启
// 默认的混淆规则文件
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
// 依赖块,指定构建当前模块所需要的依赖
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
我们在实际的开发中其实经常会经常遇到需要多渠道打包的场景,这项配置也可以在此进行 默认情况下,是不会创建给设置,需要自己添加productFlavors
块,用于为应用定制版本,直接加在android
块下
首先,需要使用flavorDimensions
指定维度,其实就是添加一个标签,表明该特性的归属,分类的依据是什么 比如根据是否是vip,分别指定专业版和社区版,这样就会有两套apk,具体打包内容需要另外配置了,这里并未给出
flavorDimensions "vip" // 标签
productFlavors {
community { // 社区版
applicationId "com.minos.gradledemo.community"
dimension "vip"
}
profession { // 专业版
applicationId "com.minos.gradledemo.profession"
dimension "vip"
}
}
配置完后,进行打包 这个时候,发现可以选用不同的脚本对应配置的不同渠道版本 最终生成的就是配置的两种版本的apk
2.4. 属性文件
另外,还有两个.properties
的属性文件,在第三个红框中
位置:项目根目录下
作用:指定Gradle
构建工具包本身的属性参数设置 首先看一下gradle.properties
的内容
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
以键值对的形式给出一些配置,比如守护进程的参数、代码格式之类的配置
而local.properties
主要是本地项目的一些配置,最常见的就是sdk
本地目录的指定
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=C:\Users\XXX\AppData\Local\Android\Sdk
其实,还有中间一个红框没有提到,因为这涉及到了另一个内容:Gradle Wrapper
3. Gradle Wrapper
这是Gradle
官方对于Gradle Wrapper
工作流的描述 首先解释一下Wrapper
,这是包装器,怎么理解呢?
可以想象这样一个场景,小明买了一台电脑(整套的),我要一台和小明一样的电脑,这个时候,我可以自己找配件自己组装,当然,更加简单和保险的方式当然是直接找小明要个购买链接,我也来一套一样的(提供这种套装就是Gradle Wrapper
的职责)
回到Gradle
这种项目构建工具的初衷,是需要标准化、自动化项目的构建、打包流程,那么Gradle Wrapper
将项目需要的这种Gradle
构建工具标准制定好,团队内部的其他成员去拉取项目代码,进行构建时,如果本地没有指定的Gradle
,那么Gradle Wrapper
会根据配置的路径到云端下载一份,解压,然后提供给构建流程以完成项目的构建,这也就是上图描述的工作流,很多小伙伴第一次构建项目卡住估计不少都是因为Gradle
没能从云端下载下来吧
了解到这里,接着上面一节的内容,打开之前中间红框对应的gradle-wrapper.properties
#Sat Jul 16 10:02:53 CST 2022
distributionBase=GRADLE_USER_HOME # 解包后存储的主目录
distributionUrl=https://services.gradle.org/distributions/gradle-7.3.3-bin.zip # 包下载路径
distributionPath=wrapper/dists # 指定目录的子目录
zipStorePath=wrapper/dists # 压缩包存储主目录
zipStoreBase=GRADLE_USER_HOME # 压缩包存储子目录
似乎就能从中发现这些配置的目的是为了标准化构建的工具集
gradle-wrapper.jar
文件包含下载指定版本Gradle
远程包的相关逻辑代码
除此以外,在最后一个红框中还有两个与Gradle Wrapper
相关的文件,分别是gradlew
和gradlew.bat
,分别对应于Linux和Windows下执行Gradle
命令的包装器脚本
有了这层包装,gradlew
命令相较于gradle
命令显得更加可靠,另外也可以方便地进行版本的升级以及自定义Gradle Wrapper
Gradle User Manual
配置 build | Android 开发者 | Android Developers (google.cn)
The Gradle Wrapper