Gradle学习篇(一)---Android构建系统

418 阅读6分钟

Android 构建系统会编译应用资源和源代码,然后将它们打包成 APK 或 Android App Bundle 文件,供您测试、部署、签名和分发。Android Studio 使用高级构建工具包 Gradle 来自动执行和管理构建流程,同时也允许您自行指定灵活的 build 配置。每项 build 配置均可定义各自的一组代码和资源,同时重复利用所有应用版本共用的部分。Android Plugin for Gradle 与该构建工具包搭配使用,提供专用于构建和测试 Android 应用的流程和可配置设置。

Gradle 和 Android 插件独立于 Android Studio 运行。这意味着,您可以在 Android Studio 内、计算机上的命令行或未安装 Android Studio 的计算机(如持续集成服务器)上构建 Android 应用。如果您不使用 Android Studio,可以学习如何从命令行构建和运行应用。无论您是从命令行、在远程计算机上还是使用 Android Studio 构建项目,构建过程的输出都相同。

Android 构建系统非常灵活,让您可以在不修改应用核心源代码文件的情况下执行自定义的 build 配置。本部分将介绍 Android 构建系统的工作原理,以及它如何帮助您对多项 build 配置进行自定义和自动化处理。如果您只是想详细了解如何部署应用,请参阅在 Android Studio 中构建和运行应用。如需立即开始使用 Android Studio 创建自定义 build 配置,请参阅配置 build 变体

构建流程

构建流程涉及许多将项目转换成 Android 应用软件包 (APK) 或 Android App Bundle (AAB) 文件的工具和流程。构建流程非常灵活,因此了解它的一些底层工作原理会很有帮助。

image.png

典型 Android 应用模块的构建流程(如图 1 所示)按照以下常规步骤执行:

  1. 编译器将您的源代码转换成 DEX 文件(Dalvik 可执行文件,其中包括在 Android 设备上运行的字节码),并将其他所有内容转换成编译后的资源。

  2. 打包器将 DEX 文件和编译后的资源组合成 APK 或 AAB(具体取决于所选的 build 目标)。 必须先为 APK 或 AAB 签名,然后才能将应用安装到 Android 设备或分发到 Google Play 等商店。

  3. 打包器使用调试或发布密钥库为 APK 或 AAB 签名:

    1. 如果您构建的是调试版应用(即专门用来测试和分析的应用),则打包器会使用调试密钥库为应用签名。Android Studio 会自动使用调试密钥库配置新项目。
    2. 如果您构建的是打算对外发布的发布版应用,则打包器会使用发布密钥库(您需要进行配置)为应用签名。如需创建发布密钥库,请参阅在 Android Studio 中为应用签名
  4. 在生成最终 APK 之前,打包器会使用 zipalign 工具对应用进行优化,以减少其在设备上运行时所占用的内存。

构建流程结束时,您将获得应用的调试版或发布版 APK/AAB,以用于部署、测试或向外部用户发布。

build配置文件

Gradle配置文件

settings.gradle 文件位于项目的根目录下,用于定义项目级代码库设置,并告知 Gradle 在构建应用时应将哪些模块包含在内。

rootProject.name = "LowCarbonApp"
include ':app'
include ':form'
include ':MPChartLib'
include ':wheelview'
include ':pickerview'
include ':WheelPicker'
include ':magicindicator'
include ':multiple-status-view'

不过,多模块项目需要指定应包含在最终 build 中的每个模块。

顶层build文件

顶层build.gradle文件位于项目的根目录下,用于定义适用于项目中所有模块的依赖项。默认情况下,顶层build文件使用plugins代码块定义项目中所有模块共用的Gradle依赖项。此外,顶层build文件还包含用于清理build目录的代码。

buildscript {
    repositories {
        google()
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.0.3'
        //这里版本不能是1.5.20
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21"
        classpath 'com.google.dagger:hilt-android-gradle-plugin:2.38.1'
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter()
        maven { url "https://jitpack.io" }
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

配置项目全局属性 对于包含多个模块的Android项目,可能有必要在项目级别定义某些属性并在所有模块之间共享这些属性。为此,可以将额外的属性添加到顶层build.gradle文件内的ext代码块中。

buildscript {
    ext.kotlin_version = '1.6.10'
    ext.kotlin_version = '1.5.21'
    repositories {
        google()
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:7.0.1"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10"
        classpath 'com.google.dagger:hilt-android-gradle-plugin:2.38.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url "https://jitpack.io" }
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

ext {
    //统一配置常用SDK版本和库版本
    minSdkVersion = 21
    compileSdkVersion = 32
    targetSdkVersion = 31

    buildToolsVersion = '30.0.3'
   ...
   //动态权限
    permissionsVersion = '4.2.0'
}

如需在同一项目中的模块访问这些属性,请在该模块的build.gradle文件中使用以下语法

android {
    compileSdk rootProject.compileSdkVersion
    buildToolsVersion rootProject.buildToolsVersion

    defaultConfig {
        minSdk rootProject.minSdkVersion
        targetSdk rootProject.targetSdkVersion

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        consumerProguardFiles "consumer-rules.pro"
    }
    ...
    dependencies{
    ...
    //动态权限
    api "org.permissionsdispatcher:permissionsdispatcher:$rootProject.permissionsVersion"
    ...
    }
    

模块级build文件

模块级build.gradle文件位于每个project/module/目录下,用于为其所在的特定模块配置build设置。可以通过配置这些build设置提供自定义打包选项(如额外的build类型和产品变种),以及覆盖main/应用清单或顶层build.gradle文件中的设置。

plugins {
    id("com.android.application")
}

android {
    namespace = "com.example.myapp"
    compileSdk = 28
    buildToolsVersion = "30.0.2"
    defaultConfig {
        applicationId = "com.example.myapp"
        minSdk = 15
        targetSdk = 28
        versionCode = 1
        versionName = "1.0"
    }

    buildTypes {
        getByName("release") {
            isMinifyEnabled = true // Enables code shrinking for the release build type.
            proguardFiles(
                getDefaultProguardFile("proguard-android.txt"),
                "proguard-rules.pro"
            )
        }
    }


    flavorDimensions = "tier"
    productFlavors {
        create("free") {
            dimension = "tier"
            applicationId = "com.example.myapp.free"
        }

        create("paid") {
            dimension = "tier"
            applicationId = "com.example.myapp.paid"
        }
    }
}

dependencies {
    implementation(project(":lib"))
    implementation("com.android.support:appcompat-v7:28.0.0")
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Gradle属性文件

Gradle还包含两个属性文件,它们位于项目的根目录下,可用于指定Gradle构建工具包本身的设置:

Gradle.properties

local.properties

为构建系统配置本地环境属性,其中包括:

  • ndk.dir - NDK 的路径。此属性已被废弃。NDK 的所有下载版本都将安装在 Android SDK 目录下的 ndk 目录中。
  • sdk.dir - SDK 的路径。
  • cmake.dir - CMake 的路径。
  • ndk.symlinkdir - 在 Android Studio 3.5 及更高版本中,创建指向 NDK 的符号链接,该符号链接的路径可比 NDK 安装路径短。

源代码集

Android studio按逻辑关系将每个模块的源代码和资源分组为源代码集。模块的main/源代码集包含其所有build变体共用的代码和资源。其他源代码集目录是可选的,在配置新的build变体时,Android studio不会自动为你创建这些目录。不过,创建类似于main/的源代码集有助于组织Gradle仅在构建特定应用版本时才应使用的文件和资源:

src/main/ 此源代码集包含所有build变体共用的代码和资源

src/buildType/ 创建此源代码集可加入特定 build 类型专用的代码和资源。

src/productFlavor/ 创建此源代码集可加入特定产品变种专用的代码和资源。

src/productFlavorBuildType/ 创建此源代码集可加入特定 build 变体专用的代码和资源。

例如,如需生成应用的“fullDebug”版本,构建系统需要合并来自以下源代码集的代码、设置和资源:

  • src/fullDebug/(build 变体源代码集)
  • src/debug/(build 类型源代码集)
  • src/full/(产品变种源代码集)
  • src/main/(主源代码集)