讀懂Android項目中的Gradle

用了這麼久 AS,要是還是不明白 Gradle,真的說不過去。從網上下載一個項目跑不起來,Gradle 各種報錯束手無措,現在我們就整體看看這個 Gradle 到底是什麼,我這裏新建一個 Android 項目。

一、Project 中的 Gradle

先來看下根目錄與 Gradle 相關的文件。

  1. .gradle
    該文件夾是編譯後生成的文件,不需要關注。

  2. 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 不僅可以設置網絡地址,還可以設置爲本地路徑。

  3. 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 文件夾
    }
    
  4. 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 文件中的值了。

  5. 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 並編譯代碼。

  6. 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'
}
  1. apply plugin表示的是應用插件。
    • 使用 android 插件:
      apply plugin: 'com.android.application'
      // apply plugin: 'com.android.library'
      
      能使用上面插件的原因是,在根目錄的 build.gradle 中配置了 Android 插件依賴。
      classpath 'com.android.tools.build:gradle:4.0.1'
      
    • 使用 kotlin 插件:
      apply plugin: 'kotlin-android'
      apply plugin: 'kotlin-android-extensions'
      
      能使用上面插件的原因是,在根目錄的 build.gradle 中配置了 Kotlin 插件依賴。
      classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
      
  2. dependencies表示依賴配置,這裏指的是工程依賴;在根目錄的 build.gradle 文件中,buildscript 裏面定義的 dependencies 指的是插件依賴,不是同一個概念。
  3. 這裏沒有定義 repositories,是因爲在根目錄的 build.gradle 文件中,已經定義了全部項目的工程依賴倉庫,不需要每個 Module 再重複定義。
    allprojects {
        repositories {
            google()
            jcenter()
        }
    }
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章