Android Gradle 的入门
一前言
当初的 Android 利用都是采纳 Android Studio 来开发的,AS 默认是采纳 Gradle 作为构建工具的。通常开发者能够不须要了解任何 Gradle 的脚本配置,就能够开发出一个 APP。然而,当你想做一些更智能的操作时,比方批改打包后的输入目录、进步打包速度等等,就必须对 Gradle 有比拟深刻的理解。Gradle 脚本是基于 Groovy 语言来编译执行的,在这之前最好要对 Groovy 语言有所理解。
二:AS 目录下的 gradle
1.Android 视图下咱们能够清晰看到 gradle 配置
(1)gradle-wrapper.properties(Gradle Version) 为 gradle 的版本配置信息。
所需的 Gradle 版本
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
这个与 Project 下的 build.gradle 对应的插件版本
buildscript {
repositories {google()
jcenter()}
dependencies {
classpath "com.android.tools.build:gradle:4.1.0"// 对应着 Gradle 版本号
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
(2)gradle.properties(Project Properties)是与以后我的项目相干的一个配置文件,次要包含一些以后我的项目中须要用到的键值对信息。
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
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
#SDK 下 build 工具的版本号
buildToolsVer=29.0.0
#app 外部版本号
verCode=16
#app 内部版本号
verName=1.2
(3)settings.gradle(Project Settings)为工程的设置文件,通知 gradle 以后工程的组成部分,比方有多少个子工程或者模块
include ':module_red'
include ':module_goods'
include ':module_free'
include ':module_me'
include ':module_login'
include ':common_base'
include ':app'
rootProject.name = "KuaiLaiTao"
(4)build.gradle(Project)为 root project(这里咱们称我的项目的根目录为 root project)下的 gradle 配置文件,该配置文件个别用来做一些全局性的配置。
apply from:"config.gradle"// 利用一个 config.gradle 的配置文件
// 全局配置构建工具的 classpath 和近程仓库门路,这里个别配置为 gradle 的,因为我的项目在构建过程中须要应用 gradle 去执行,当然如果你应用到了一些额定的插件,比方注解处理器,也能够放在这里。buildscript {
repositories {// 这里是 gradle 脚本执行所需依赖,别离是对应的 maven 库和插件
google()// 从 Android Studio3.0 后新增了 google()配置,能够援用 google 上的开源我的项目
jcenter()// 是一个相似于 github 的代码托管仓库,申明了 jcenter()配置,能够轻松援用 jcenter 上的开源我的项目
}
dependencies {
classpath "com.android.tools.build:gradle:3.5.4"// 此处是 android 的插件 gradle,gradle 是一个弱小的我的项目构建工具
classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.0'//butterKnife 组件化第一步
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {// 这里是我的项目自身须要的依赖,比方我的项目所需的 maven 库
google()
jcenter()
maven {url "http://mvn.gt.igexin.com/nexus/content/repositories/releases/"}// 个推的 Maven 库
}
}
// 运行 gradle clean 时,执行此处定义的 task 工作。// 该工作继承自 Delete,删除根目录中的 build 目录。// 相当于执行 Delete.delete(rootProject.buildDir)。// gradle 应用 groovy 语言,调用 method 时能够不必加()。task clean(type: Delete) {delete rootProject.buildDir}
(5)build.gradle(Module)为 module 下的 gradle 配置,该配置只对该 module 失效。
// 第一行代码利用了 Android 程序的 gradle 插件,作为 Android 的应用程序,这一步是必须的,因为 plugin 中提供了 Android 编译、测试、打包等等的所有 task。plugins {id 'com.android.application'}
//android: 这是编译文件中最大的代码块,对于 android 的所有非凡配置都在这里,这就是又咱们后面的申明的 plugin 提供的。android {
compileSdkVersion 30// 设置编译时用的 Android 版本
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.ruan.mygitignore"// 我的项目包名
minSdkVersion 16// 我的项目最低兼容的版本
targetSdkVersion 30// 我的项目的指标版本
versionCode 1// 版本号
versionName "1.0"// 版本名称
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"// 表明要应用 AndroidJUnitRunner 进行单元测试
}
/**
* 新增 debug 和 release 签名配置属性 */
signingConfigs {// 自动化打包配置,签名
debug {// 测试环境
keyAlias 'androiddebugkey'
keyPassword 'android'
storePassword 'android'
storeFile file('C:/Users/Administrator/.android/debug.keystore')
}
release{// 线上环境
keyAlias 'rocky'
keyPassword 'rockyruan'
storePassword 'rockyruan'
storeFile file('F:/soudaoProject/MyGitignore/rocky_ruan.jks')
}
}
buildTypes {// 生产 / 测试环境配置
release {// 生产环境
buildConfigField("boolean", "LOG_DEBUG", "false")// 配置 Log 日志
buildConfigField("String", "URL_PERFIX", "\"https://release.cn/\"")// 配置 URL 前缀
minifyEnabled false// 是否对代码进行混同
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'// 指定混同的规定文件
signingConfig signingConfigs.release// 设置签名信息
pseudoLocalesEnabled false// 是否在 APK 中生成伪语言环境,帮忙国际化的货色,个别应用的不多
zipAlignEnabled true// 是否对 APK 包执行 ZIP 对齐优化,减小 zip 体积,减少运行效率
applicationIdSuffix 'test'// 在 applicationId 中增加了一个后缀,个别应用的不多
versionNameSuffix 'test'// 在 applicationId 中增加了一个后缀,个别应用的不多
}
debug {// 测试环境
buildConfigField("boolean", "LOG_DEBUG", "true")// 配置 Log 日志
buildConfigField("String", "URL_PERFIX", "\"https://test.com/\"")// 配置 URL 前缀
minifyEnabled false// 是否对代码进行混同
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'// 指定混同的规定文件
signingConfig signingConfigs.debug// 设置签名信息
debuggable false// 是否反对断点调试
jniDebuggable false// 是否能够调试 NDK 代码
renderscriptDebuggable false// 是否开启渲染脚本就是一些 c 写的渲染办法
zipAlignEnabled true// 是否对 APK 包执行 ZIP 对齐优化,减小 zip 体积,减少运行效率
pseudoLocalesEnabled false// 是否在 APK 中生成伪语言环境,帮忙国际化的货色,个别应用的不多
applicationIdSuffix 'test'// 在 applicationId 中增加了一个后缀,个别应用的不多
versionNameSuffix 'test'// 在 applicationId 中增加了一个后缀,个别应用的不多
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation 'com.scwang.smart:refresh-layout-kernel:2.0.3' // 外围必须依赖
implementation 'com.scwang.smart:refresh-header-classics:2.0.3'// 经典刷新头
implementation 'com.scwang.smart:refresh-footer-classics:2.0.3' // 经典加载
implementation 'com.google.android:flexbox:2.0.1'
implementation 'com.squareup.okhttp3:okhttp:3.8.0'
implementation 'com.squareup.okio:okio:1.12.0'
implementation 'com.google.code.gson:gson:2.6.2'
//rxjava2
implementation 'io.reactivex.rxjava2:rxjava:2.2.20'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
//RxLifecycle
implementation 'com.trello.rxlifecycle3:rxlifecycle:3.1.0'
implementation 'com.trello.rxlifecycle3:rxlifecycle-components:3.1.0'
//AutoDispose
implementation 'com.uber.autodispose:autodispose:0.6.1'
implementation 'com.uber.autodispose:autodispose-android-archcomponents:0.6.1'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation "com.github.bumptech.glide:okhttp3-integration:4.11.0"
implementation "androidx.work:work-runtime:2.5.0"
}
defaultConfig 就是程序的默认配置,留神,如果在 AndroidMainfest.xml 外面定义了与这里雷同的属性,会以这里的为主。
这里最有必要要阐明的是 applicationId 的选项:在咱们已经定义的 AndroidManifest.xml 中,那里定义的包名有两个用处:一个是作为程序的惟一辨认 ID, 避免在同一手机装两个一样的程序;另一个就是作为咱们 R 资源类的包名。在以前咱们批改这个 ID 会导致所有用援用 R 资源类的中央都要批改。然而当初咱们如果批改 applicationId 只会批改以后程序的 ID, 而不会去批改源码中资源文件的援用。
buildTypes: 定义了编译类型,针对每个类型咱们能够有不同的编译配置,不同的编译配置对应的有不同的编译命令。默认的有 debug、release 的类型。
dependencies: 是属于 gradle 的依赖配置。它定义了以后我的项目须要依赖的其余库。
三:Gradle 构建生命周期
在解析 Gradle 的编译过程之前咱们须要了解在 Gradle 中十分重要的两个对象。Project 和 Task
每个我的项目的编译至多有一个 Project, 一个 build.gradle 就代表一个 project, 每个 project 外面蕴含了多个 task,task 外面又蕴含很多 action,action 是一个代码块,外面蕴含了须要被执行的代码
在编译过程中,Gradle 会依据 build 相干文件,聚合所有的 project 和 task,执行 task 中的 action。因为 build.gradle 文件中的 task 十分多,先执行哪个后执行那个须要一种逻辑来保障。这种逻辑就是依赖逻辑,简直所有的 Task 都须要依赖其余 task 来执行,没有被依赖的 task 会首先被执行。所以到最初所有的 Task 会形成一个 有向无环图(DAG Directed Acyclic Graph)的数据结构。
无论什么时候执行 Gradle 构建,都会运行 3 个不同的生命周期阶段:初始化、配置、执行。
- 初始化(Initialization):Gradle 为每个我的项目创立一个 Project 实例,在多我的项目构建中,Gradle 会找出哪些项目依赖须要参加到构建中。
- 配置(Configuration):执行所有我的项目的构建脚本,也就是执行每个我的项目的 build.gradle 文件。这里须要留神的是,task 里的配置代码也会在这个阶段执行。
- 执行(Execution):Gradle 依照依赖程序顺次执行 task。
执行程序:
setting 开始配置
setting 配置实现
> Configure project :
根 build.gradle 开始配置
根 build.gradle 配置实现
> Configure project :app
app build.gradle 开始配置
app build.gradle 配置实现
所有模块都已配置实现
assembleDebug 会打出 debug 包
assembleRelease 会打出 release 包
assemble 会同时打出 debug 包和 release 包
1.android Task:
能够获取的是 debug 下的签名文件和 Release 下签名文件的 MD5 值,SHA1 值,SHA256 值
2.build Task:
构建依赖的编译的执行 assemble
3.build setup
4.clean up
5.help
6.install
在设施上装置一个 Debug/Release 版本
7.other
点击 assembleRelease 打包生成的 apk 在 app 下 build-outputs-relase 包下
显示是一个未被签名的正式包
然而如果 app 下 build.gradle 配置
buildTypes {
/* 正式版本 */
release {
minifyEnabled false// 代码混同
/* 代码混同规定 */
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
//debuggable false // 这个构建类型是否应该生成可调式的 apk
signingConfig signingConfigs.release // 设置默认调用上方咱们刚配置的 signingConfigs.release
}
}
signingConfig signingConfigs.release 调用下面配置好的签名文件
还能够命令行应用 在 Terminal 下应用 gradlew assembleRelease
8.verification
build task 依赖于 check 工作,然而不依赖于 connectedCheck 或者 deviceCheck,执行 check 工作时 Lint 会产生一些相干文件,能够在
END: 常识须要一直的吸取