Android Gradle 构建指令生成规则

32 阅读2分钟

Android 构建工具生成的 Gradle 构建任务遵循特定的命名规则,它们由 buildTypesproductFlavors 的组合决定


1. 构建任务的命名规则

1.1 基本规则

构建任务的命名格式为:

[**Action**][ProductFlavor][BuildType]

其中:

  • Action:构建操作,如 assemble(用于生成 APK)或 bundle(用于生成 AAB)。
  • ProductFlavor:定制产品,可为空。如果未定义,任务名称中不会包含此部分。
  • BuildType:构建类型,如 debugrelease

1.2 命名示例

构建配置Gradle 任务名称描述
无 Flavor + DebugassembleDebug生成 Debug APK
无 Flavor + ReleasebundleRelease生成 Release AAB
pad Flavor + DebugassemblePadDebug生成 Pad Debug APK
mobile Flavor + ReleasebundleMobileRelease生成 Mobile Release AAB

2. 任务生成逻辑

Gradle 根据以下条件生成任务:

2.1 buildTypes 定义

build.gradle 中,buildTypes 定义不同的构建类型,例如:

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
    debug {
        applicationIdSuffix ".debug"
        debuggable true
    }
}
  • 定义了 releasedebug 类型,因此会生成相应的任务名称后缀。

2.2 productFlavors 定义

如果定义了定制产品(Flavors),Gradle 会为每个定制生成组合任务,例如:

productFlavors {
    pad {
        dimension "device"
    }
    mobile {
        dimension "device"
    }
}
  • 定义了 padmobile ,因此任务名称会包含这些定制名称。

2.3 合并规则

Gradle 会为每种 ProductFlavorBuildType 的组合生成构建任务。例如:

buildTypes {
    debug {}
    release {}
}

productFlavors {
    pad {}
    mobile {}
}

生成的任务包括:

  • assemblePadDebug
  • assemblePadRelease
  • assembleMobileDebug
  • assembleMobileRelease
  • bundlePadDebug
  • bundlePadRelease
  • bundleMobileDebug
  • bundleMobileRelease

3. 特殊情况

3.1 无 productFlavors

如果未定义 productFlavors,则任务名称不包含定制部分。例如:

buildTypes {
    debug {}
    release {}
}

生成的任务:

  • assembleDebug
  • assembleRelease
  • bundleDebug
  • bundleRelease

3.2 单一定制产品

当只有一个定制维度时,任务名称仍然完整。例如:

productFlavors {
    pad {}
}

生成的任务:

  • assemblePadDebug
  • assemblePadRelease
  • bundlePadDebug
  • bundlePadRelease

4. 运行构建任务

4.1 命令行运行

可以通过以下方式运行特定的构建任务:

# 构建 APK
./gradlew assemblePadDebug

# 构建 AAB
./gradlew bundleMobileRelease

4.2 查看所有任务

运行以下命令查看所有可用任务:

./gradlew tasks

5. 注意事项

  • 确保所有定义的 buildTypesproductFlavors 的组合具有明确的用途。
  • 确保拼写和配置文件正确,否则可能会导致任务名称不生效。

6. 自定义构建任务

可以根据项目需求自定义任务:

task customBuild(type: Exec) {
    group = "Custom Tasks"
    description = "Build Free Release APK and upload it to the server."
    commandLine "./gradlew", "assembleFreeRelease"
    doLast {
        println "Build complete for Free Release!"
    }
}

运行以下命令即可执行自定义任务:

./gradlew customBuild

7. 总结

任务命名规则基于 assemble 或 bundle + Flavor 名称 + BuildType 名称。

默认任务适用于没有 productFlavors 的情况。

• 使用 ./gradlew tasks 可查看所有任务。

• 自定义任务可根据项目需求灵活添加。

8. 示例

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

android {
    compileSdk 34

    defaultConfig {
        applicationId "com.example.myapp"
        minSdk 21
        targetSdk 34
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        debug {
            debuggable true
            applicationIdSuffix ".debug"
            versionNameSuffix "-debug"
        }
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    flavorDimensions "device_type"
    productFlavors {
        mobile {
            dimension "device_type"
            applicationId "com.example.myapp.mobile"
            versionNameSuffix "-mobile"
            resValue "string", "app_name", "MyApp Mobile"
        }
        pad {
            dimension "device_type"
            applicationId "com.example.myapp.pad"
            versionNameSuffix "-pad"
            resValue "string", "app_name", "MyApp Pad"
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }

    buildFeatures {
        viewBinding true
    }

    packagingOptions {
        resources {
            excludes += "/META-INF/{AL2.0,LGPL2.1}"
        }
    }

    applicationVariants.configureEach { variant ->
        variant.outputs.configureEach {
            outputFileName = "${variant.name}-${variant.versionName}.apk"
        }
    }
}

dependencies {
    // ...
}