Skip to content

Build Types 配置

源:Android 官方文档 - 配置 build 变体

Build Types(构建类型)定义了 Gradle 在构建和打包应用时使用的特定属性。每个构建类型通常对应开发生命周期的不同阶段,如开发调试、内部测试、正式发布等。

默认Build Types是

Android Studio 在创建新模块时会自动创建两个默认的构建类型:

Debug

Debug 构建类型虽然不显示在构建配置文件中,但 Android Studio 会使用以下默认配置:

kotlin
buildTypes {
    getByName("debug") {
        isDebuggable = true
        isMinifyEnabled = false
        isShrinkResources = false
        signingConfig = signingConfigs.getByName("debug")
    }
}

默认特性

  • isDebuggable = true:允许应用被调试
  • 使用调试密钥库签名(自动生成)
  • 不启用代码压缩和混淆
  • 不启用资源缩减
  • 构建速度更快

Release

Release 构建类型需要手动配置,通常包含以下设置:

kotlin
buildTypes {
    getByName("release") {
        isMinifyEnabled = true
        isShrinkResources = true
        proguardFiles(
            getDefaultProguardFile("proguard-android-optimize.txt"),
            "proguard-rules.pro"
        )
        signingConfig = signingConfigs.getByName("release")
    }
}

典型特性

  • isMinifyEnabled = true:启用代码压缩和混淆
  • isShrinkResources = true:启用资源缩减
  • 使用发布密钥库签名
  • 优化APK大小和性能

配置Build Types

基础配置

在模块级 build.gradle.kts 文件的 android 块内配置构建类型:

kotlin
android {
    defaultConfig {
        manifestPlaceholders["hostName"] = "www.example.com"
    }
    
    buildTypes {
        // 访问并配置已存在的 debug 类型
        getByName("debug") {
            applicationIdSuffix = ".debug"
            isDebuggable = true
            versionNameSuffix = "-DEBUG"
        }
        
        // 访问并配置 release 类型
        getByName("release") {
            isMinifyEnabled = true
            isShrinkResources = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
}
groovy
android {
    defaultConfig {
        manifestPlaceholders = [hostName:"www.example.com"]
    }
    
    buildTypes {
        debug {
            applicationIdSuffix '.debug'
            debuggable true
            versionNameSuffix '-DEBUG'
        }
        
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

创建自定义Build Type

除了默认的 debug 和 release,可以创建自定义构建类型:

kotlin
android {
    buildTypes {
        // 创建一个新的 staging 构建类型
        create("staging") {
            // 使用 initWith 复制已有构建类型的配置
            initWith(getByName("debug"))
            
            // 自定义配置
            manifestPlaceholders["hostName"] = "internal.example.com"
            applicationIdSuffix = ".staging"
            versionNameSuffix = "-staging"
            isDebuggable = true
            
            // 可以启用部分优化
            isMinifyEnabled = false
            isShrinkResources = false
        }
        
        // 创建预发布构建类型
        create("preRelease") {
            initWith(getByName("release"))
            applicationIdSuffix = ".pre"
            versionNameSuffix = "-pre"
        }
    }
}
groovy
android {
    buildTypes {
        staging {
            initWith debug
            manifestPlaceholders = [hostName:"internal.example.com"]
            applicationIdSuffix '.staging'
            versionNameSuffix '-staging'
            debuggable true
            minifyEnabled false
            shrinkResources false
        }
        
        preRelease {
            initWith release
            applicationIdSuffix '.pre'
            versionNameSuffix '-pre'
        }
    }
}

initWith 的作用

  • 复制另一个构建类型的所有配置
  • 只需修改需要不同的属性
  • 减少配置重复

常用Build Type属性

Application ID相关

kotlin
buildTypes {
    getByName("debug") {
        // 为 Application ID 添加后缀
        applicationIdSuffix = ".debug"
    }
}

允许在同一设备上安装不同构建类型的APK。详见 模块配置 - Application ID

版本相关

kotlin
buildTypes {
    getByName("debug") {
        // 为版本名添加后缀
        versionNameSuffix = "-DEBUG"
    }
}

代码优化相关

kotlin
buildTypes {
    getByName("release") {
        // 启用代码压缩、优化和混淆
        isMinifyEnabled = true
        
        // 启用资源缩减
        isShrinkResources = true
        
        // ProGuard/R8 配置文件
        proguardFiles(
            getDefaultProguardFile("proguard-android-optimize.txt"),
            "proguard-rules.pro"
        )
        
        // 优化级别(仅 R8)
        // 可选值:null(默认), "none", "simple", "full"
        // AGP 8.0+ 默认启用完整优化
    }
}

详见 R8 压缩与混淆

调试相关

kotlin
buildTypes {
    getByName("debug") {
        // 启用调试
        isDebuggable = true
        
        // 启用 JNI 调试
        isJniDebuggable = true
        
        // 启用渲染脚本调试
        isRenderscriptDebuggable = true
        
        // 禁用渲染脚本优化
        renderscriptOptimLevel = 0
    }
}

签名配置

kotlin
android {
    signingConfigs {
        create("release") {
            storeFile = file("release.keystore")
            storePassword = "password"
            keyAlias = "release"
            keyPassword = "password"
        }
    }
    
    buildTypes {
        getByName("release") {
            // 关联签名配置
            signingConfig = signingConfigs.getByName("release")
        }
    }
}

详见 应用签名配置

清单占位符

kotlin
buildTypes {
    getByName("debug") {
        manifestPlaceholders["hostName"] = "debug.example.com"
        manifestPlaceholders["apiKey"] = "debug-api-key-123"
    }
    
    getByName("release") {
        manifestPlaceholders["hostName"] = "api.example.com"
        manifestPlaceholders["apiKey"] = "prod-api-key-456"
    }
}

AndroidManifest.xml 中使用:

xml
<meta-data
    android:name="com.example.API_KEY"
    android:value="${apiKey}" />

<activity
    android:name=".WebViewActivity"
    android:host="${hostName}" />

详见 Manifest 合并机制 - 构建变量注入

NDK相关

kotlin
buildTypes {
    getByName("release") {
        ndk {
            // 仅包含特定 ABI
            abiFilters += listOf("armeabi-v7a", "arm64-v8a")
        }
    }
}

详见 NDK 构建配置

其他属性

kotlin
buildTypes {
    create("benchmark") {
        // 是否嵌入 Micro APK(用于 Wear OS)
        isEmbedMicroApp = false
        
        // 是否启用代码压缩伪本地化
        isPseudoLocalesEnabled = false
        
        // 是否为多 Dex 启用旧版合并
        isMultiDexEnabled = true
        
        // 是否将测试代码作为库模块打包
        isTestCoverageEnabled = false
        
        // 是否启用 ZIP 对齐
        isZipAlignEnabled = true
        
        // 是否生成默认源代码集
        isDefault = false
    }
}

Build Type实践案例

案例一:多环境配置

应用通常需要连接不同的后端环境(开发、测试、预发布、生产):

kotlin
android
{
    buildTypes {
        getByName("debug") {
            applicationIdSuffix = ".debug"
            versionNameSuffix = "-debug"
            isDebuggable = true
            isMinifyEnabled = false
            
            buildConfigField("String", "API_URL", "\"https://dev-api.example.com\"")
            buildConfigField("boolean", "ENABLE_LOGGING", "true")
            manifestPlaceholders["appName"] = "MyApp Debug"
        }
        
        create("staging") {
            initWith(getByName("debug"))
            applicationIdSuffix = ".staging"
            versionNameSuffix = "-staging"
            
            buildConfigField("String", "API_URL", "\"https://staging-api.example.com\"")
            buildConfigField("boolean", "ENABLE_LOGGING", "true")
            manifestPlaceholders["appName"] = "MyApp Staging"
            
            // Staging 可以启用部分优化验证
            isMinifyEnabled = true
            proguardFiles(
                getDefaultProguardFile("proguard-android.txt"),
                "proguard-rules.pro"
            )
        }
        
        getByName("release") {
            isMinifyEnabled = true
            isShrinkResources = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
            
            buildConfigField("String", "API_URL", "\"https://api.example.com\"")
            buildConfigField("boolean", "ENABLE_LOGGING", "false")
            manifestPlaceholders["appName"] = "MyApp"
            
            signingConfig = signingConfigs.getByName("release")
        }
    }
}
groovy
android {
    buildTypes {
        debug {
            applicationIdSuffix '.debug'
            versionNameSuffix '-debug'
            debuggable true
            minifyEnabled false
            
            buildConfigField 'String', 'API_URL', '"https://dev-api.example.com"'
            buildConfigField 'boolean', 'ENABLE_LOGGING', 'true'
            manifestPlaceholders = [appName: 'MyApp Debug']
        }
        
        staging {
            initWith debug
            applicationIdSuffix '.staging'
            versionNameSuffix '-staging'
            
            buildConfigField 'String', 'API_URL', '"https://staging-api.example.com"'
            buildConfigField 'boolean', 'ENABLE_LOGGING', 'true'
            manifestPlaceholders = [appName: 'MyApp Staging']
            
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            
            buildConfigField 'String', 'API_URL', '"https://api.example.com"'
            buildConfigField 'boolean', 'ENABLE_LOGGING', 'false'
            manifestPlaceholders = [appName: 'MyApp']
            
            signingConfig signingConfigs.release
        }
    }
}

在代码中使用:

kotlin
val apiUrl = BuildConfig.API_URL
if (BuildConfig.ENABLE_LOGGING) {
    Log.d(TAG, "API URL: $apiUrl")
}

案例二:性能基准测试构建

创建专门用于性能基准测试的构建类型:

kotlin
android {
    buildTypes {
        create("benchmark") {
            // 基于 release 配置
            initWith(getByName("release"))
            
            // 保留符号以便分析
            isMinifyEnabled = true
            isShrinkResources = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "benchmark-rules.pro"
            )
            
            // 可调试以便使用 Profiler
            isDebuggable = true
            
            // 使用 release 签名
            signingConfig = signingConfigs.getByName("debug")
            
            // 添加后缀避免与 release 冲突
            applicationIdSuffix = ".benchmark"
            versionNameSuffix = "-benchmark"
        }
    }
}

benchmark-rules.pro 保留基准测试需要的符号:

proguard
# 保留所有方法名用于性能分析
-keepnames class ** { *; }

# 保留行号信息
-keepattributes SourceFile,LineNumberTable

常见问题

BuildConfig字段被标记为废弃 AGP 8.0+

从 AGP 8.0 开始,buildConfigField 生成的 BuildConfig 类默认被禁用。需要在 build.gradle.kts 中显式启用:

kotlin
android {
    buildFeatures {
        buildConfig = true
    }
}

如何为特定Build Type配置依赖

kotlin
dependencies {
    // 仅用于 debug 构建
    debugImplementation("com.squareup.leakcanary:leakcanary-android:2.13")
    
    // 仅用于 release 和 staging 构建
    "releaseImplementation"("com.example:crash-reporter:1.0")
    "stagingImplementation"("com.example:crash-reporter:1.0")
}

如何在代码中判断当前Build Type

kotlin
if (BuildConfig.DEBUG) {
    // Debug 构建特有逻辑
}

// 或者通过 Build Type 名称
val buildType = BuildConfig.BUILD_TYPE
when (buildType) {
    "debug" -> {
        // Debug 逻辑
    }
    "staging" -> {
        // Staging 逻辑
    }
    "release" -> {
        // Release 逻辑
    }
}

最佳实践

  1. 合理使用 initWith:避免配置重复,从最相似的构建类型继承
  2. Application ID 后缀:为非 release 构建类型添加后缀,允许多版本共存
  3. 环境隔离:不同构建类型使用不同的 API 端点和配置
  4. 签名管理:开发构建使用 debug 签名,生产构建使用安全的 release 签名
  5. 优化验证:在 staging 构建中启用代码压缩,提前发现混淆问题
  6. BuildConfig 字段:通过 buildConfigField 注入环境相关配置
  7. 清单占位符:使用 manifestPlaceholders 动态配置清单值

API参考

完整的 Build Type 配置属性请参考官方 API 文档: