用了這麼久 AS,要是還是不明白 Gradle,真的說不過去。從網上下載一個項目跑不起來,Gradle 各種報錯束手無措,現在我們就整體看看這個 Gradle 到底是什麼,我這裏新建一個 Android 項目。
一、Project 中的 Gradle
先來看下根目錄與 Gradle 相關的文件。
-
.gradle
該文件夾是編譯後生成的文件,不需要關注。
-
gradle
這個文件夾是 Gradle Wrapper 的版本配置,實現了無需手動下載 Gradle,通過配置即可自動下載,需要與 gradlew 配合使用。
- gradle-wrapper.jar:包含 Gradle 運行時的邏輯代碼。
- gradle-wrapper.properties:負責配置包裝器運行時行爲的屬性文件,用來配置使用哪個版本的 Gradle 等屬性。
#Sun Jun 28 14:04:41 CST 2020 # Gradle 解壓後存儲的根目錄,類似於 JAVA_HOME distributionBase=GRADLE_USER_HOME # distributionBase + distributionPath 就是 Gradle 解壓後的存放位置 distributionPath=wrapper/dists # Gradle壓縮包存儲根目錄,類似於 JAVA_HOME zipStoreBase=GRADLE_USER_HOME # zipStoreBase + zipStorePath 就是 Gradle 壓縮包的存放位置 zipStorePath=wrapper/dists # Gradle 壓縮包的下載地址,可以在這裏配置需要使用的 Gradle 版本 distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
另外,distributionUrl 不僅可以設置網絡地址,還可以設置爲本地路徑。
-
build.gradle
Gradle 根工程配置文件,這是 Project 下的 build.gradle,後面還會說到 Module 下的 build.gradle。// Top-level build file where you can add configuration options common to all sub-projects/modules. // 頂級構建文件,您可以在其中添加對所有子項目/模塊通用的配置選項。 buildscript {// 所有的子模塊都會讀取到這個配置裏面的內容,在這裏定義 Gradle 插件所在的倉庫和依賴 ext.kotlin_version = "1.3.72"// 創建一個變量,用於控制 kotlin 版本號 repositories {// 構建插件倉庫 google()// 使用 google 倉庫,https://dl.google.com/dl/android/maven2/ jcenter()// 使用 jcenter 倉庫,https://jcenter.bintray.com/ } dependencies {// 構建插件依賴配置 // 引入 Android 的 Gradle 插件 classpath 'com.android.tools.build:gradle:4.0.1' // 引入 Kotlin 的 Gradle 插件 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files // 注意:不要將應用程序依賴項放在這裏;它們屬於單個模塊生成.gradle文件夾 } } allprojects {// 全部項目的配置,給 Module repositories {// 工程依賴倉庫 google()// 使用 google 倉庫,https://dl.google.com/dl/android/maven2/ jcenter()// 使用 jcenter 倉庫,https://jcenter.bintray.com/ } } task clean(type: Delete) {// 創建一個名爲 clean 的任務 delete rootProject.buildDir// 刪除全部子項目的 build 文件夾 }
-
gradle.properties
Gradle 屬性配置文件,值會添加到 project 當中。# 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 # 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 # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official
上面看到的鍵值,是新建項目時自動生成的,當然還可以添加新的鍵值,然後在 gradle 文件中取到。
例如,在上面文件的最後,添加一個:
kotlin_version=1.3.72
這樣就可以移除 build.gradle 中定義的
ext.kotlin_version = "1.3.72"
,依然可以編譯通過,不過此時的kotlin_version
,使用是該 gradle.properties 文件中的值了。 -
gradlew 和 gradlew.bat
Gradle Wrapper 啓動腳本,根據上面 gradle 文件夾中配置的版本,執行對應的腳本。- gradlew:Linux、Mac 平臺下,用於執行 Gralde 命令的包裝器腳本。
- gradlew.bat:Windows 平臺下,用於執行 Gralde 命令的包裝器腳本。
Gradle Wrapper 的作用是簡化 Gradle 本身的安裝、部署。不同版本的項目可能需要不同版本的 Gradle,手工部署的話比較麻煩,而且可能產生衝突,所以需要 Gradle Wrapper 幫你搞定這些事情。Gradle Wrapper 是 Gradle項目的一部分。
當從版本庫下載代碼之後,如果你本機安裝過 Gradle,當然直接直接編譯運行既可。
但是對沒有安裝 Gradle 的用戶,可以執行項目根目錄下的 gradlew 腳本 ,將會在 gradle-wrapper.properties 中的 ~/.gradle/wrapper/dists 目錄中首次下載並安裝 Gradle 並編譯代碼。
-
settings.gradle
Gradle 工程初始化配置文件,它的作用就是用於多項目構建。include ':app' rootProject.name = "Kotlin"
如果有多個 Module,就會有多個
include
,大致就是下面的樣子:include ':app' include ':library' rootProject.name = "Kotlin"
二、Module 中的 Gradle
再來看下 app 目錄下 Gradle 相關的文件,只有一個 build.gradle。
這個就是 Module 下的 build.gradle,內容不同於 Project 下的 build.gradle。
apply plugin: 'com.android.application'// 表示是一個 android 的應用
// apply plugin: 'com.android.library'// 表示是一個 android library,與上面只能二選一
apply plugin: 'kotlin-android'// 使用 kotlin 插件,如果使用 kotlin 必寫
apply plugin: 'kotlin-android-extensions'// 使用 kotlin 擴展插件,不是必寫
android {// 由於使用了 apply plugin: 'com.android.application' 所以可以用
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.ff.kotlin"
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
// 單元測試
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {// 指定生成安裝文件的配置,常有兩個子包:release,debug
release {
minifyEnabled false// 是否對代碼進行混淆,true表示混淆
// proguard-android-optimize.txt默認的混淆文件(SDK目錄/tools/proguard/)
// proguard-rules.pro自行添加混淆規則文件(相應module的目錄下)
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {// 工程依賴配置
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
-
apply plugin
表示的是應用插件。- 使用 android 插件:
能使用上面插件的原因是,在根目錄的 build.gradle 中配置了 Android 插件依賴。apply plugin: 'com.android.application' // apply plugin: 'com.android.library'
classpath 'com.android.tools.build:gradle:4.0.1'
- 使用 kotlin 插件:
能使用上面插件的原因是,在根目錄的 build.gradle 中配置了 Kotlin 插件依賴。apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- 使用 android 插件:
-
dependencies
表示依賴配置,這裏指的是工程依賴;在根目錄的 build.gradle 文件中,buildscript
裏面定義的dependencies
指的是插件依賴,不是同一個概念。 - 這裏沒有定義
repositories
,是因爲在根目錄的 build.gradle 文件中,已經定義了全部項目的工程依賴倉庫,不需要每個 Module 再重複定義。allprojects { repositories { google() jcenter() } }