Skip to Content

Build Variants

Build Variants cho phép bạn tạo nhiều phiên bản khác nhau của ứng dụng từ một codebase duy nhất. Mỗi variant có thể có code, resources, và cấu hình riêng.

Build Variant = Build Type + Product Flavor

Thành phầnMô tảVí dụ
Build TypeCách build ứng dụngdebug, release, staging
Product FlavorPhiên bản nội dungdemo, full, free, paid
Build VariantKết hợp type + flavordemoDebug, fullRelease

Build Types

Build Types định nghĩa cách Gradle build và package ứng dụng. Mặc định Android Studio tạo 2 build types:

Cấu hình Build Types

android { buildTypes { debug { // Debug được cấu hình mặc định: debuggable = true applicationIdSuffix = ".debug" versionNameSuffix = "-debug" // Không minify để build nhanh isMinifyEnabled = false } release { isMinifyEnabled = true isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } // Custom build type create("staging") { // Kế thừa từ debug initWith(getByName("debug")) applicationIdSuffix = ".staging" versionNameSuffix = "-staging" // Môi trường staging buildConfigField("String", "API_URL", "\"https://staging.api.com\"") } } }

Các thuộc tính Build Type

Thuộc tínhMô tảMặc định DebugMặc định Release
isDebuggableCho phép attach debuggertruefalse
isMinifyEnabledBật code shrinking (R8)falsefalse
isShrinkResourcesLoại bỏ resources không dùngfalsefalse
applicationIdSuffixSuffix cho applicationId
versionNameSuffixSuffix cho versionName
signingConfigSigning configurationdebug keystore(cần cấu hình)

💡 Mẹo: Debug build được tự động sign với debug keystore. Release build cần cấu hình signing riêng.


Product Flavors

Product Flavors tạo các phiên bản khác nhau của ứng dụng với nội dung hoặc tính năng khác nhau.

Khai báo Product Flavors

android { // Bắt buộc: Khai báo flavor dimensions flavorDimensions += "version" productFlavors { create("demo") { dimension = "version" applicationIdSuffix = ".demo" versionNameSuffix = "-demo" // Custom build config fields buildConfigField("Boolean", "IS_DEMO", "true") buildConfigField("Int", "MAX_ITEMS", "10") } create("full") { dimension = "version" buildConfigField("Boolean", "IS_DEMO", "false") buildConfigField("Int", "MAX_ITEMS", "Integer.MAX_VALUE") } } }

Sử dụng BuildConfig

// Trong code Kotlin if (BuildConfig.IS_DEMO) { showDemoLimitation() } val maxItems = BuildConfig.MAX_ITEMS

⚠️ Quan trọng: Để sử dụng BuildConfig, phải bật buildFeatures.buildConfig = true trong build.gradle.kts.


Flavor Dimensions

Khi có nhiều “chiều” khác nhau cho product flavors, sử dụng flavor dimensions:

android { flavorDimensions += listOf("version", "api") productFlavors { // Dimension: version create("demo") { dimension = "version" applicationIdSuffix = ".demo" } create("full") { dimension = "version" } // Dimension: api create("minApi24") { dimension = "api" minSdk = 24 } create("minApi28") { dimension = "api" minSdk = 28 } } }

Build Variants được tạo

Gradle tạo variants từ tất cả combinations:

demoMinApi24Debug demoMinApi24Release demoMinApi28Debug demoMinApi28Release fullMinApi24Debug fullMinApi24Release fullMinApi28Debug fullMinApi28Release

Ví dụ thực tế: App với môi trường Dev/Prod

android { namespace = "com.example.myapp" compileSdk = 35 defaultConfig { applicationId = "com.example.myapp" minSdk = 24 targetSdk = 35 versionCode = 1 versionName = "1.0.0" } buildFeatures { buildConfig = true } flavorDimensions += "environment" productFlavors { create("dev") { dimension = "environment" applicationIdSuffix = ".dev" versionNameSuffix = "-dev" // Môi trường development buildConfigField("String", "API_BASE_URL", "\"https://dev.api.example.com\"") buildConfigField("String", "API_KEY", "\"dev_api_key_123\"") buildConfigField("Boolean", "ENABLE_LOGGING", "true") // Resource values resValue("string", "app_name", "MyApp Dev") } create("staging") { dimension = "environment" applicationIdSuffix = ".staging" versionNameSuffix = "-staging" buildConfigField("String", "API_BASE_URL", "\"https://staging.api.example.com\"") buildConfigField("String", "API_KEY", "\"staging_api_key_456\"") buildConfigField("Boolean", "ENABLE_LOGGING", "true") resValue("string", "app_name", "MyApp Staging") } create("prod") { dimension = "environment" buildConfigField("String", "API_BASE_URL", "\"https://api.example.com\"") buildConfigField("String", "API_KEY", "\"prod_api_key_789\"") buildConfigField("Boolean", "ENABLE_LOGGING", "false") resValue("string", "app_name", "MyApp") } } buildTypes { debug { isMinifyEnabled = false } release { isMinifyEnabled = true isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } } }

Sử dụng trong code

// NetworkModule.kt object NetworkModule { val retrofit: Retrofit = Retrofit.Builder() .baseUrl(BuildConfig.API_BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .apply { if (BuildConfig.ENABLE_LOGGING) { client( OkHttpClient.Builder() .addInterceptor(HttpLoggingInterceptor().setLevel(Level.BODY)) .build() ) } } .build() }

Source Sets cho Variants

Mỗi variant có thể có source code và resources riêng:

app/src/ ├── main/ # Common source │ ├── java/ │ └── res/ ├── debug/ # Debug build type specific │ └── java/ ├── release/ # Release build type specific ├── dev/ # Dev flavor specific │ ├── java/ │ └── res/ ├── prod/ # Prod flavor specific │ └── res/ └── devDebug/ # Dev + Debug combination └── java/

Thứ tự merge source sets

Variant source set > Build type > Flavor > main

Ví dụ với variant devDebug:

  1. src/devDebug/ (nếu có)
  2. src/debug/
  3. src/dev/
  4. src/main/

Filter Variants

Loại bỏ các variants không cần thiết:

android { flavorDimensions += listOf("version", "api") productFlavors { create("demo") { dimension = "version" } create("full") { dimension = "version" } create("minApi24") { dimension = "api" } create("minApi28") { dimension = "api" } } } // Filter variants androidComponents { beforeVariants { variantBuilder -> // Loại bỏ demo + minApi28 combinations if (variantBuilder.productFlavors.containsAll( listOf("version" to "demo", "api" to "minApi28")) ) { variantBuilder.enable = false } } }

Signing Configuration

Cấu hình signing cho từng build type:

android { signingConfigs { // Debug đã có sẵn, không cần khai báo create("release") { storeFile = file("keystore/release.jks") storePassword = System.getenv("KEYSTORE_PASSWORD") keyAlias = System.getenv("KEY_ALIAS") keyPassword = System.getenv("KEY_PASSWORD") } } buildTypes { release { signingConfig = signingConfigs.getByName("release") // ... } } }

🚨 Chú ý: KHÔNG commit passwords vào source control! Sử dụng environment variables hoặc local.properties.

Sử dụng local.properties

// build.gradle.kts import java.util.Properties val localProperties = Properties().apply { val localPropertiesFile = rootProject.file("local.properties") if (localPropertiesFile.exists()) { load(localPropertiesFile.inputStream()) } } android { signingConfigs { create("release") { storeFile = file(localProperties.getProperty("RELEASE_STORE_FILE", "")) storePassword = localProperties.getProperty("RELEASE_STORE_PASSWORD", "") keyAlias = localProperties.getProperty("RELEASE_KEY_ALIAS", "") keyPassword = localProperties.getProperty("RELEASE_KEY_PASSWORD", "") } } }

Chọn Build Variant trong Android Studio

  1. Mở panel Build Variants (View → Tool Windows → Build Variants)
  2. Chọn variant cho mỗi module
  3. Click Sync nếu cần

Hoặc build từ command line:

# Build variant cụ thể ./gradlew assembleDevDebug ./gradlew assembleProdRelease # Build tất cả variants của một type ./gradlew assembleDebug ./gradlew assembleRelease # Build AAB ./gradlew bundleProdRelease

Tóm tắt

ConceptMục đíchVí dụ
Build TypeCách build (debug settings, minification)debug, release, staging
Product FlavorPhiên bản ứng dụngdemo/full, free/paid, dev/prod
Flavor DimensionNhóm các flavorsversion, api, environment
Build VariantBuild type + Flavor(s)demoDebug, prodRelease
Source SetCode/resources cho variantsrc/demo/, src/debug/

📚 Tham khảo

Last updated on