Autoaprendizagem Gradle - Introdução
Exemplo de criação de aplicativos Android (gradle.org)
Configurar compilação | Desenvolvedores Android | Desenvolvedores Android (google.cn)
Ao desenvolver aplicativos Android, Gradle
é sempre difícil não atrair nossa atenção. Depois que o projeto atinge um certo nível, Gradle
o uso adequado de
1. Processo de criação do projeto Android
Em anexo está um fluxograma oficial de construção de aplicativos Android
- Em primeiro lugar, o código do projeto escrito, arquivos de recursos, interface aidl e outras dependências serão eventualmente convertidos em arquivos .class pelo compilador e, em seguida, compilados em arquivos .dex pela ferramenta Dex novamente.
- O empacotador empacota arquivos de recursos e arquivos .dex de maneira uniforme para gerar arquivos .apk
- Em seguida, o KeyStore correspondente assina o arquivo .apk
- Se for Release KeyStore, a ferramenta zipalign será usada para otimizar o alinhamento do apk para reduzir a sobrecarga de memória em tempo de execução.
2. O arquivo de configuração padrão gerado pelo projeto
No início da criação do projeto, o Android Studio criará uma série Gradle
de arquivos de configuração e definirá algumas configurações padrão. Esses arquivos de configuração Groovy
são gravados, incluindo DSL
a configuração do elemento, que reduz o limite de uso. Alguns arquivos de configuração correspondem aos padrões do projeto . Antes personalização, primeiro Você precisa entender o papel que esses arquivos predefinidos desempenham no projeto. O projeto recém-criado inclui principalmente os seguintes Gradle
arquivos relacionados
2.1. Arquivo de configurações do Gradle (settings.gradle)
Este arquivo corresponde exatamente ao settings.gradle
local da terceira parte da figura acima : sob o diretório raiz do projeto
Role : define as configurações da base de código no nível do projeto e decide quais módulos incluir no momento da compilação
// 该块定义查找和下载插件的存储库
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. Arquivos de compilação de nível superior
即第三个框中的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
Manual do usuário do GradleConfigurando a
compilação | Desenvolvedores Android | Desenvolvedores Android (google.cn)
O Gradle Wrapper