读懂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()
        }
    }
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章